内部如何在Enum中进行序列化/反序列化? jvm如何在(序列化)之前和之后(反序列化)生成相同的哈希码?
答案 0 :(得分:6)
序列化专门处理enum
。基本上,它只存储对其class
的引用和常量的名称。反序列化后,此信息用于查找enum
类型的现有运行时对象。
因此,如果在同一运行时中反序列化enum
常量,则将获得已序列化的相同运行时实例。
但是,在另一个JVM中反序列化时,哈希码可能会有所不同。但是具有相同的哈希码不是单身人士的必需标准。重要的一点是永远不要有另一个类的实例,这是有保证的,因为序列化实现永远不会创建enum
类型的实例,而只会查找现有的常量。
答案 1 :(得分:2)
内部如何在Enum中进行序列化/反序列化?
您无法在Java中序列化枚举。您只能序列化对Enum的引用。这意味着如果你的枚举有任何私有字段,它们将不会被写入或恢复。
jvm如何在(序列化)之前和之后(反序列化)生成相同的哈希码?
JVM中没有指定JVM如何生成hashCode,实际上是在多个实现的源代码中。但是,Oracle 8更新45 JVM在重新启动后以相同的顺序生成相同的hashCodes。
Object[] objs = new Object[5];
for(int i=0;i<objs.length;i++) {
objs[i] = new Object();
}
RetentionPolicy[] values = RetentionPolicy.values();
System.out.println(objs+": "+objs.hashCode());
for (Object obj : objs) {
System.out.println(obj+": "+obj.hashCode());
}
for (RetentionPolicy policy : values) {
System.out.println(policy+": "+policy.hashCode());
}
如果您使用new Object[5]
运行它,则会打印
[Ljava.lang.Object;@677327b6: 1735600054
java.lang.Object@14ae5a5: 21685669
java.lang.Object@7f31245a: 2133927002
java.lang.Object@6d6f6e28: 1836019240
java.lang.Object@135fbaa4: 325040804
java.lang.Object@45ee12a7: 1173230247
SOURCE: 856419764
CLASS: 621009875
RUNTIME: 1265094477
如果我将数组大小减小到2,则会打印出来。
[Ljava.lang.Object;@677327b6: 1735600054
java.lang.Object@14ae5a5: 21685669
java.lang.Object@7f31245a: 2133927002
SOURCE: 1836019240
CLASS: 325040804
RUNTIME: 1173230247
请注意它是如何以相同的顺序生成相同的hashCodes。如果我完全注释掉Object[]
代码。
SOURCE: 1735600054
CLASS: 21685669
RUNTIME: 2133927002
每次运行程序时看到相同hashcode的原因是它在检查枚举的hashCodes之前创建了相同数量的hashCodes。
注意:在您要求它降低创建对象的成本之前,对象没有系统hashCode。
答案 2 :(得分:0)
我写了一个简单的枚举类。 例如:
public enum EnumTest{
IND(1),
ORG(2);
int deger;
EnumTest(int deger){
this.deger = deger;
}
}
编译这个枚举类后,我们可以使用javap工具使用javap EnumTest命令。
public final class EnumTest extends java.lang.Enum{
public static final EnumTest IND;
public static final EnumTest ORG;
int deger;
public static EnumTest[] values();
public static EnumTest valueOf(java.lang.String);
static {};
}
从上面的javap工具生成的文本可以看出,枚举实例是静态的,静态变量不能序列化。