java序列化之Serializable接口研究

    今天在工作中遇到一个java反序列化的失败的问题,问题是这样的:Child类继承自Parent类,实现了Serializable接口并指定serialVersionUID;Parent类实现了Serializable接口,但是没有指定serialVersionUID。Child对象存储在redis中,get的时候直接返回Child对象。现在对Parent类进行调整,调整之后从Redis中获取Child对象的时候,报错:    

java.io.InvalidClassException: com.guowl.kata.serializable.Parent; local class incompatible: stream classdesc serialVersionUID = -2208631449244519299, local class serialVersionUID = -7852931829867773699
	at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:617)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
	at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
	at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1515)
	at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1769)
	at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1348)
	at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370)
	at com.guowl.kata.serializable.Child.main(Child.java:50)
    就这个时机,把Serializable以及serialVersionUID属性在不用场景下的作用,进行研究整理,结论如下:

    事先把Child进行序列化,然后测试反序列化的情况:

java序列化之Serializable接口研究_第1张图片


    综上所述,只要serialVersionUID 一致,类就能正常的反序列话;serialVersionUID 不指定,系统会默认生成一个,但是类的内容(包括属性、方法)有变化的时候该版本号会自动变化,这时反序列化就会失败。

    针对这种情况,可以把属性定义为transient类型的:private transient Stringphone2,这样可以正常反序列化。但是如果是方法体有变更的话,就不行了,加上@Transient注解也没有效果。



你可能感兴趣的:(java-java基础)