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

Nic*_*lai 18 java serialization java-8

从版本8开始,Java具有基于值的的概念.这是为了准备将来很可能允许定义值类型的未来版本.两个定义/描述都提到序列化(我添加的粗体):

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

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

关于未来的价值类型:

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

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

但我不知道序列化如何发挥作用.为什么它被认为是"身份敏感机制"?为什么它"以对象为基础进行基于身份的区分"

Bri*_*etz 13

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

  • 有什么可以替代呢?我如何序列化具有localdate字段的对象 (11认同)
  • 这个答案只指出了为什么身份可能在反序列化过程中发挥作用.但是,我不明白为什么这意味着"基于价值的类[不应该被序列化",这似乎是最初的问题.(即使OP似乎对答案感到满意.) (6认同)
  • 另外,如果是这样的话,为什么要使LocalDate Serializable? (6认同)
  • 为什么LocalDateTime实现Serializable? (2认同)

Mar*_*nik 5

想一想当序列化的对象图有一个循环时会发生什么。在这种情况下,除非有特定的机制来检测和解决循环,否则序列化算法将进入无限循环。众所周知,Java的序列化允许循环对象图,因此存在这种机制。

现在考虑一个循环的定义:图形包含一个可以从其自身到达的对象。该定义指的是对象的标识,这意味着该机制必须考虑对象的标识以跟踪周期。在实现级别,这是通过维护IdentityHashMap所有可见实例来实现的,并且该类依赖Object.identityHashCode()

您引用的句子说明了在Java的未来版本中将如何解决此问题:值类型将得到特殊处理,以便循环检测将依赖于其自身的equalshashCode方法而不是==and identityHashCode