java - 反序列化对象时是否会忽略意外字段?

标签 java serialization

来自文档:

http://docs.oracle.com/javase/8/docs/platform/serialization/spec/version.html#a5172

Incompatible changes to classes are those changes for which the guarantee of interoperability cannot be maintained. The incompatible changes that may occur while evolving a class are:

Deleting fields - If a field is deleted in a class, the stream written will not contain its value. When the stream is read by an earlier class, the value of the field will be set to the default value because no value is available in the stream. However, this default value may adversely impair the ability of the earlier version to fulfill its contract.

etc...

在这里,将“删除字段”作为不兼容的更改意味着:

有例如一个可序列化的 A 类:

public class A implements Serializable {
    private static final long serialVersionUID = -13921739827197L;

    private B fieldB;
    private C fieldC;
    // ... getters and setters for both fields
}

如果我现在序列化这个类,fieldBfieldC都会被序列化(当然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。

如果现在我将此序列化传递给一个 JVM 实例,其中使用了 A 类的先前版本(因此具有 fieldBfieldC 的实例),作为序列化对象A 类的序列化中没有 fieldB,结果将是带有 A 类旧版本的实例fieldB 设置为 null(默认值,就像“添加字段”兼容更改时一样)。当然这可能会导致“空”指针异常和意外结果,这就是为什么 Oracle 说它应该被视为“不兼容的更改”。

但是,如果出现相反的情况怎么办?

例如,如果发生 反序列化 类 A 的旧版本实例(同时具有 fieldBfieldC)并且JVM 有更新版本的 A 类(因此,没有 fieldB)?

序列化 API 将如何处理这个问题?它会简单地丢弃 fieldB 吗?

最佳答案

规范在这一点上具有误导性。

从序列化本身的角度来看,删除是兼容的:也就是说,它不会触发IncompatibleClassChangeException。规范试图传达的是应用程序 可能会遇到不兼容问题。

但它不应列在规范中的“不兼容更改”下:从序列化的角度来看,它是与字段插入或重新排序具有完全相同性质的更改:兼容更改。

也就是说,为了最终真正回答您的问题,流中多余的字段将被简单地丢弃。

关于java - 反序列化对象时是否会忽略意外字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28962336/

相关文章:

Java Jackson 如何在自定义序列化程序中为对象使用默认序列化程序

java - HTTP 状态 500 - 无法为 JSP : in Eclipse Luna 编译类

循环中的java变量不计数

java - 手动 GC 调用的用例?

java - 使用 ByteArrayInputStream 构造 ObjectInputStream 后没有可用字节

c# - 在 C# 中保存字典 <String, Int32> - 序列化?

java - 如何导航到 Eclipse 3.4.1 中的书签?

java - 文件上传中的内容处理

c# - DataContractSerialiser 和 Serializable 的问题

c# - 使用 WCF 将类序列化为由 xsd.exe 生成的 JSON