发布于2026-07-11 阅读(0)
扫一扫,手机访问
父类不实现Serializable?writeObject()直接抛异常;serialVersionUID得自己声明,还得按兼容性规则更新;transient和static字段的继承规则一样生效,至于构造函数——序列化里根本没它什么事。

如果父类没实现Serializable,那ObjectOutputStream一调用writeObject(),立马就给你一个NotSerializableException——哪怕子类已经实现了接口也不行。原因很简单:Ja va序列化是递归遍历整个对象图的,父类的字段(哪怕是private的)都会被写入字节流,所以父类不能缺席。
常见错误就是只给最末级子类加implements Serializable,运行时直接报错,告诉你“class com.example.Base is not serializable”。
implements Serializable。Externalizable自定义逻辑。当父类或子类在后续版本中修改了字段(增删改类型)、重命名、或者没有显式定义serialVersionUID,反序列化时就可能栽跟头。JVM会基于类结构自动生成一个默认值,但只要类结构一变化,这个值也跟着变,校验就过不去了。
实际业务场景中,实体类随需求迭代,但旧数据文件还得读,这问题就特别让人头疼。
private static final long serialVersionUID = 1L;。transient或新增可空字段),serialVersionUID可以保持不变;如果破坏了兼容性(比如删字段、改类型),那就必须更新这个值,并配套迁移策略。1L,靠人工控制变更节奏。transient修饰的字段不会被序列化,这个规则对父类字段同样适用。但要注意:子类没法“取消”父类字段的transient属性,也没法通过子类逻辑“恢复”它。
性能方面得留个心:避免在深层继承链中大量使用非transient的大对象引用(比如List、嵌套Map),否则序列化体积和耗时会指数级增长。
transient是安全做法,子类无需重复声明。static字段无论在哪一层定义,都不会进入序列化流——这点常被误解成“子类能覆盖父类static行为”,实际上JVM层面就直接跳过了。readObject(ObjectInputStream)方法,在其中手动赋值。Ja va默认序列化机制不通过构造函数重建对象,而是用JVM特殊机制直接分配内存并填充字段值。因此父类是否提供无参构造函数,不影响序列化/反序列化流程——但有个关键例外:如果父类没实现Serializable,JVM会尝试调用它的无参构造器来初始化字段,这时候才真的需要它。
容易踩的坑:在父类中写了带参构造器、又删了默认无参构造,同时父类没实现Serializable,结果反序列化失败报InvalidClassException: no valid constructor。
Serializable,就完全不用管构造器是否存在、是否public。ja va.util.Date的子类),而你又必须序列化,那就得让该子类实现Externalizable,自己控制writeExternal/readExternal逻辑。writeObject/readObject方法,必须显式调用defaultWriteObject()/defaultReadObject()才能保证父类字段被正常处理。继承深度越大,各层serialVersionUID协调和字段兼容性判断就越难;最容易被忽略的是父类来自外部包却未实现Serializable,这时连编译都过不去,更别说运行时序列化了。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8