面试题答案
一键面试serialVersionUID设置方式
- 显式设置相同值:
- 在父类和所有子类中显式地设置相同的
serialVersionUID
值。例如:
public class Parent implements Serializable { private static final long serialVersionUID = 1L; // 其他属性和方法 } public class Child extends Parent { private static final long serialVersionUID = 1L; // 其他属性和方法 }
- 这样设置可以确保整个继承体系内对象在序列化和反序列化时,JVM能够识别对象的版本一致性。因为
serialVersionUID
是JVM用来验证序列化对象的版本一致性的标识,相同的值表示这些类在序列化方面是兼容的。
- 在父类和所有子类中显式地设置相同的
- 父类设置,子类默认:
- 在父类中显式设置
serialVersionUID
,子类不设置,由编译器自动生成(虽然不推荐)。例如:
public class Parent implements Serializable { private static final long serialVersionUID = 1L; // 其他属性和方法 } public class Child extends Parent { // 未显式设置serialVersionUID // 其他属性和方法 }
- 这种情况下,子类会继承父类的
serialVersionUID
相关行为。但编译器自动生成的serialVersionUID
可能会因为类的微小变化(如方法签名改变等不影响序列化语义的变化)而改变,导致潜在的兼容性问题。
- 在父类中显式设置
不同设置方式的潜在问题
- 父类和子类设置不同值:
- 如果父类和子类设置了不同的
serialVersionUID
值,当进行反序列化时,JVM会认为这是不同版本的类,即使它们在继承体系上有联系,也会抛出InvalidClassException
异常。这是因为JVM通过serialVersionUID
来验证序列化对象的类版本一致性,不同的值意味着版本不兼容。
- 如果父类和子类设置了不同的
- 不设置让编译器自动生成:
- 对于父类和子类都不设置
serialVersionUID
,让编译器自动生成的情况,由于编译器生成serialVersionUID
的算法会基于类的结构(包括属性、方法签名等),类结构的任何微小变化都可能导致生成不同的serialVersionUID
。这在维护和更新类时,很容易造成反序列化失败。比如只是在子类中添加了一个不参与序列化的私有方法,编译器生成的serialVersionUID
就可能改变,导致之前序列化的对象无法正确反序列化。
- 对于父类和子类都不设置
- 父类未设置,子类设置:
- 如果父类没有设置
serialVersionUID
,而子类设置了。在反序列化时,同样可能因为父类和子类serialVersionUID
的不一致性导致问题。父类没有设置serialVersionUID
时,其serialVersionUID
依赖于编译器生成,可能与子类设置的不一致,从而引发InvalidClassException
异常。
- 如果父类没有设置