反序列化 Java 中的数组

Deserializing enum in Java

我可以看到抽象 class enum 实现了标记接口 Serializable 的 readObject() 方法,它抛出 InvalidObjectException。

private void readObject(ObjectInputStream in) throws IOException,
        ClassNotFoundException {
        throw new InvalidObjectException("can't deserialize enum");
}

private void readObjectNoData() throws ObjectStreamException {
        throw new InvalidObjectException("can't deserialize enum");
}

我的理解是在反序列化枚举时我们可以得到 InvalidObjectException。 但是我可以反序列化我的枚举。

根据我的理解,如果提供了 readResolve() 方法实现,那么 jvm 在反序列化过程中会调用此方法,所以从技术上讲,我应该得到一个错误,但我得到的是对象。

我的代码:

enum Person50{
    OBJECT;
}
private static void serializationSingletonEnum() throws Exception{
        Person50 p50 = Person50.OBJECT;
        System.out.println("hashCode 1:" +p50.hashCode());

        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("enumFile.ser"));
        oos.writeObject(p50);
        oos.close();

        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("enumFile.ser"));
        Person50 p15 = (Person50)ois.readObject();
        System.out.println("hashCode after:" +p15.hashCode());
}

输出:

hashCode 1:1435804085
hashCode after:1435804085

我认为我可能犯了一些愚蠢的错误,或者我对序列化调用的理解可能不正确。

它起作用的原因是 Enum 序列化过程忽略了 readObject() 实现

根据official documentaion

1.12 Serialization of Enum Constants Enum constants are serialized differently than ordinary serializable or externalizable objects. The serialized form of an enum constant consists solely of its name; field values of the constant are not present in the form. To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.lang.Enum.valueOf method, passing the constant's enum type along with the received constant name as arguments. Like other serializable or externalizable objects, enum constants can function as the targets of back references appearing subsequently in the serialization stream.

The process by which enum constants are serialized cannot be customized: any class-specific writeObject, readObject, readObjectNoData, writeReplace, and readResolve methods defined by enum types are ignored during serialization and deserialization. Similarly, any serialPersistentFields or serialVersionUID field declarations are also ignored--all enum types have a fixed serialVersionUID of 0L. Documenting serializable fields and data for enum types is unnecessary, since there is no variation in the type of data sent.