Java 枚举集在类版本控制方面有什么特点?

Java 枚举集在类版本控制方面有什么特点?,java,enums,Java,Enums,这两者都强调 枚举集在内部表示为位向量 现在我想知道,当通过线路将(标准Java序列化的)EnumSet对象发送到可能具有不同版本的底层Enum类的其他JVM时,会发生什么行为 换句话说:当我发送一些Set时,很可能在另一个JVM上的反序列化过程中引发异常(在我的JVM使用另一个JVM不知道的一些MyEnum.NEW\u GUY)。在这种情况下,反序列化尝试实例化另一个JVM上的类中不存在的枚举常量 但是假设EnumSet不传输enum常量实例(但只是一个位集,其中有些位为真,有些位为假)-当序

这两者都强调

枚举集在内部表示为位向量

现在我想知道,当通过线路将(标准Java序列化的)EnumSet对象发送到可能具有不同版本的底层Enum类的其他JVM时,会发生什么行为

换句话说:当我发送一些
Set
时,很可能在另一个JVM上的反序列化过程中引发异常(在我的JVM使用另一个JVM不知道的一些
MyEnum.NEW\u GUY
)。在这种情况下,反序列化尝试实例化另一个JVM上的类中不存在的枚举常量

但是假设EnumSet不传输enum常量实例(但只是一个位集,其中有些位为真,有些位为假)-当序列化的EnumSet包含MyEnum.NEW_GUY时会发生什么


我试图找出一个规范来告诉我应该发生什么(而不是假设这是一个实现细节),但到目前为止运气不佳。

仅关于实现(使用Oracle Java 8),答案是:它“不仅仅”是一个位集

意思是:可以快速编写将EnumSet实例序列化为文件的测试,然后更改enum类,并运行从文件中读回该集合的代码

结果是:

  • 如果文件包含不再存在的枚举常量,则会抛出一个
    java.io.InvalidObjectException:enum常量B在com.ibm.hwmca.z.managed.TestEnum类中不存在
  • 如果所有枚举常量都存在,但它们的顺序已更改,则读取的集合仍然正确
换句话说:该测试表明,序列化枚举集确实包含比普通位集“更多”的信息。该实现能够A)检测“缺失”枚举常量,B)处理仅影响条目顺序的枚举类更改。与@Seelenvirtuose的注释相匹配,序列化的枚举集不是位向量,而是包含实际枚举常量的数组(因此对于完全相同的版本冲突是开放的)


仍在搜索所观察到的行为是否有规范。

“但假设枚举集不传输枚举常量实例”,查看源(JDK9),情况并非如此。它使用一个序列化代理来保存元素类型
Class
和一个常量数组。根据源代码:从流中读取对象后重新计算位向量。序列化只将枚举值数组写入流(除了枚举类之外)。这意味着您可以更改枚举值的顺序,也可以添加新的枚举值,只要不在集合中序列化它们。