首页 > 编程知识 正文

jdk序列化和json序列化(反序列化可以实现对象深拷贝)

时间:2023-05-06 01:56:05 阅读:69484 作者:2971

文章目录背景serialVersionUID不匹配的兼容处理

背景

Java对象序列化使用对象中的serialVersionUID专用静态常量长整数属性" private static final long "作为对象的版本号。 反序列化时,JVM会检查版本号是否与序列化时匹配,如果不匹配,序列化将失败,则抛出invalidcationg

缺省情况下,JVM为实现序列化接口的每个类生成serialVersionUID。 由于此版本ID的计算规则来自当前类信息(类名、属性、方法、修饰符等),因此如果属性发生更改,此serialVersionUID也将随之更改()

此serialVersionUID的生成与所使用的JDK相关,并且JDK可能会生成不同的版本ID。

另外,考虑到实际的业务场景,经常更改属性修改类。 使用自动生成的版本ID时,很容易发生serialVersionUID不匹配,反序列化失败。

因此,最好是手动显示生成。 大多数JAVA IDE提供了自动生成版本ID的功能。

序列化不一致的兼容处理常规序列化(序列化)和反序列化(Deserialization ) :

publicclassserializetest { publicstaticvoidmain (字符串[ ] args ) throws exception (//serializetoafile.fileoutputstreamf s .写入对象(Today ); s.writeobject (新个人) ); s.flush (; //deserializeastringandobjectfromafile.fileinputstreamin=new file inputstream ('./tmp ); 对象输入流=新对象输入流(in; system.out.println((string ) rd.readObject ) ); system.out.println((Person ) rd.readObject ) ); 使用ObjectOutputStream序列化为文件,然后使用ObjectInputStream反序列化。 如果serialVersionUID不匹配,此方法将报告错误。

处理这种不一致也很容易。 由于在取消序列化时使用ObjectInputStream实现,因此在本例中,您可以自定义CompatibleInputStream以继承ObjectInputStream,然后使用readClassDescriptor方法

如果目标数据的Class版本号和本地Class版本号不匹配,则缺省情况下使用本地版本的Class

publicclasscompatibleinputstreamextendsobjectinputstream { publiccompatibleinputstream (inputstream in ) throwsioexception { s @ overrideprotectedobjectstreamclassreadclassdescriptor (throwsioexception,classnotfoundexception { objectstreamclassreclasreeector //theclassinthelocaljvmthatthisdescriptorrepresents.try { local class=class.forname (resultclassdescriptor.getname ) ) } objectstreamclasslocalclassdescriptor=objectstreamclass.lookup (local class ); 本地群集描述符!=null (//onlyifclassimplementsserializablefinallonglocalsuid=localclassdescriptor.getserialversionuid ); finallongstreamsuid=resultclassdescriptor.getserialversionuid (; 流用户ID!=locals uid (//checkforserialversionuidmismatch.finalstringbuffers=new string buffer (overridingserializedclassversing s.append (streamserialversionuid=' ).append (streams uid ); 系统. out.println (s; resultclassdescriptor=localclassdescriptor; //uselocalclassdescriptorfordeserialization } } returnresultclassdescriptor; }测试:

publicclassserializetest { publicstaticvoidmain (字符串[ ] args ) Throwsexception )//eserializeastringandobjectfromafilewer 兼容性输入putstreamrd=newcompatibleinputstream (in; system.out.println((string ) rd.readObject ) ); system.out.println((Person ) rd.readObject ) ); }结果:

todayoverridingserializedclassversionmismatch : localserialversionuid=3streamserialversionuid=51412782132381055 com.wkkkkk

如果遇到Java串行化、串行版本不匹配怎么办?

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。