来自文档:
http://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a5172
对类的不兼容更改是对其进行的更改 无法保证互操作性 。不相容 在进化课程时可能发生的变化是:
删除字段 - 如果在类中删除某个字段,则会写入该流 不会包含它的价值。当流被早先读取时 class,该字段的值将被设置为默认值,因为 流中没有可用的值。但是,此默认值可能 不利地削弱了早期版本实现其能力 合同。
等...
此处,使用"删除字段"作为一种不相容的变化意味着:
例如可序列化的类A:
public class A implements Serializable {
private static final long serialVersionUID = -13921739827197L;
private B fieldB;
private C fieldC;
// ... getters and setters for both fields
}
如果我现在序列化这个类, fieldB 和 fieldC 将被序列化(当然B和C也实现Serializable)。
现在,如果我从A类中删除 fieldB :
public class A implements Serializable {
private static final long serialVersionUID = -13921739827197L;
private C fieldC;
// ... getter and setter only for fieldC
}
如果我现在尝试序列化这个类的实例,只会将fieldC序列化,因为不再有fieldB。
如果现在我将此序列化传递给使用以前版本的A类的JVM实例(因此使用 fieldB 和 fieldC 的那个),作为seriliazed对象类 A 的序列化中没有 fieldB ,结果将是 A 类的旧版本的实例< em> fieldB 设置为null
(默认值,就像&#34;添加字段&#34;兼容更改)。当然这可能导致&#34; null&#34;指针异常和意外结果,这就是为什么Oracle说它应该被认为是一个&#34;不兼容的变化&#34;。
然而,如果相反的情况会发生什么呢?
例如,如果发生旧版A类(包含 fieldB 和 fieldC )的deserialization
实例并且JVM具有A类的较新版本(因此,没有 fieldB )?
序列化API如何处理这个问题?它会简单地丢弃 fieldB 吗?
答案 0 :(得分:3)
规范在这一点上具有误导性。
从序列化本身的角度来看,删除是兼容的:也就是说,它不会触发IncompatibleClassChangeException.
规范试图传达的是应用程序可能经历不相容。
但它不应该在规范中的“不兼容的变化”下列出:从序列化的角度来看,它是与字段插入或重新排序完全相同的变化:兼容的变化。
也就是说,最后并且实际上回答了你的问题,流中的多余字段将被简单地丢弃。
答案 1 :(得分:1)
您正在阅读的相同规范有答案:
3.1 The ObjectInputStream Class
...
将丢弃流中出现但未在对象中出现的类的数据。对于在对象中出现但在流中不出现的类,类字段设置为默认值为默认值序列化。