为什么Java的基于价值的类不能被序列化?

时间:2014-10-19 14:37:13

标签: java serialization java-8

由于Version 8 Java具有value-based classes的概念。这是为了准备将来很可能允许定义value types的未来版本。两个定义/描述都提到序列化(我添加的粗体):

关于现有的基于价值的课程:

  

如果程序试图将两个引用区分为基于值的类的相等值,无论是直接通过引用相等还是间接通过引发同步,身份哈希,序列化,程序可能会产生不可预测的结果或任何其他身份敏感机制。

关于未来的价值类型:

  

通过System.identityHashCode提供的对象的默认基于身份的哈希代码也不适用于值类型。像序列化这样对内容进行基于身份的区分的内部操作要么不适用于值(因为它们不适用于基元),要么它们会使用值类型的hashCode提供的基于值的区别方法

由于未来的JVM实现可能不使用基于值的类的对象头和引用指针,因此一些限制很明显。 (例如,没有锁定JVM必须不支持的标识。锁定的引用可以被删除并在以后被另一个替换,这使得释放锁定毫无意义并将导致死锁)。

但我不知道序列化如何发挥作用。为什么它被认为是“身份敏感机制”?为什么“制作基于身份的对象区分”

2 个答案:

答案 0 :(得分:13)

序列化使用System.identityHashCode(通过IdentityHashMap)来确保反序列化产生的对象图的拓扑在拓扑上等同于输入图的拓扑。

答案 1 :(得分:4)

想想当被序列化的对象图有一个循环时会发生什么。在这种情况下,序列化算法将进入无限循环 - 除非它具有检测和解决循环的特定机制。我们都知道Java的序列化允许循环对象图,因此机制就在那里。

现在考虑一个循环的定义:该图包含一个可从其自身访问的对象。该定义引用了对象的身份,这意味着该机制必须考虑对象身份来跟踪周期。在实现级别上,这是通过维护所有已见实例的IdentityHashMap来实现的,并且该类依赖于Object.identityHashCode()

您引用的句子解释了如何在未来的Java版本中解决此问题:将对值类型进行特殊处理,以便循环检测依赖于他们自己的equalshashCode方法而不是==identityHashCode