2

为什么在反序列化期间从对象的类中删除变量不会引发异常?那么序列化中的“不兼容”更改意味着什么?我还根据Java 规范将类的字段从非静态更改为静态

不兼容。

4

2 回答 2

3

为什么在反序列化期间从对象的类中删除变量不会引发异常?

因为它不应该。请参阅对象版本控制规范,#5.6.1

"删除字段 - 如果一个类中的一个字段被删除,写入的流将不包含它的值。当流被更早的类读取时,该字段的值将设置为默认值,因为没有可用的值流。但是,此默认值可能会对早期版本履行其合同的能力产生不利影响。

“将非静态字段更改为静态或将非瞬态字段更改为瞬态 - 当依赖默认序列化时,此更改相当于从类中删除一个字段。此版本的类不会将该数据写入流,因此不会可以被早期版本的类读取。当删除一个字段时,早期版本的字段将被初始化为默认值,这可能会导致类以意想不到的方式失败。

没有关于抛出异常的内容。

于 2013-06-06T07:04:06.023 回答
1
  • 我在一次RPC调用中遇到了这样的疑问,我似乎找到了答案。
  • 我在服务器端添加了两个字段并更改了一个类的一个字段类型,然后客户端调用了一个返回旧版本类的方法。首先,我遇到了不匹配的字段类型的异常,所以我修复了这个问题,但保留了添加的字段,它运行良好,让我感到困惑。
  • 然后我来到这里,我已经阅读了规范
    • 5.6.1 不兼容的更改 - 删除字段
    • 5.6.2 兼容更改 - 添加字段
    • 他们谈论的是同一件事 - 序列化的字节码不包含反序列化对象的字段,而我们的编码是序列化的字节码包含一些字段但反序列化对象不包含。
  • 据我了解
    • 从设计上考虑,这样的反序列化特性非常有用,尤其是在 RPC 调用中,序列化函数应该包含它。
    • 深入原理,反序列化实例化客户端类(旧版本)的一个对象并设置其字段的值(可能使用反射从序列化的字节码中获取字段的值),序列化字节中的冗余字段代码静静地坐着,没有来访。
于 2015-06-25T02:12:30.327 回答