设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 重新 试卷 文件
当前位置: 首页 > 运营中心 > 建站资源 > 优化 > 正文

Java对象为啥要实现Serializable接口?(3)

发布时间:2019-05-14 23:43 所属栏目:21 来源:无敌码农
导读:对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过其IO系统转换为字节数据,从而实现持久化,而这个标记就是Serializable接口。而在反序列化的过程中则需要使用seria

对于JVM来说,要进行持久化的类必须要有一个标记,只有持有这个标记JVM才允许类创建的对象可以通过其IO系统转换为字节数据,从而实现持久化,而这个标记就是Serializable接口。而在反序列化的过程中则需要使用serialVersionUID来确定由那个类来加载这个对象,所以我们在实现Serializable接口的时候,一般还会要去尽量显示地定义serialVersionUID,如:

  1. private static final long serialVersionUID = 1L; 

在反序列化的过程中,如果接收方为对象加载了一个类,如果该对象的serialVersionUID与对应持久化时的类不同,那么反序列化的过程中将会导致InvalidClassException异常。例如,在之前反序列化的例子中,我们故意将User类的serialVersionUID改为2L,如:

  1. private static final long serialVersionUID = 2L; 

那么此时,在反序例化时就会导致异常,如下:

  1. java.io.InvalidClassException: cn.wudimanong.serializable.User; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2 
  2.     at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:687) 
  3.     at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1880) 
  4.     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1746) 
  5.     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2037) 
  6.     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1568) 
  7.     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:428) 
  8.     at cn.wudimanong.serializable.SerializableTest.readObj(SerializableTest.java:31) 
  9.     at cn.wudimanong.serializable.SerializableTest.main(SerializableTest.java:44) 

如果我们在序列化中没有显示地声明serialVersionUID,则序列化运行时将会根据该类的各个方面计算该类默认的serialVersionUID值。但是,Java官方强烈建议所有要序列化的类都显示地声明serialVersionUID字段,因为如果高度依赖于JVM默认生成serialVersionUID,可能会导致其与编译器的实现细节耦合,这样可能会导致在反序列化的过程中发生意外的InvalidClassException异常。因此,为了保证跨不同Java编译器实现的serialVersionUID值的一致,实现Serializable接口的必须显示地声明serialVersionUID字段。

此外serialVersionUID字段地声明要尽可能使用private关键字修饰,这是因为该字段的声明只适用于声明的类,该字段作为成员变量被子类继承是没有用处的!有个特殊的地方需要注意的是,数组类是不能显示地声明serialVersionUID的,因为它们始终具有默认计算的值,不过数组类反序列化过程中也是放弃了匹配serialVersionUID值的要求。

参考资料:

https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html?is-external=true

http://www.tutorialspoint.com/java/java_serialization.htm

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读