Java 中枚举字段的序列化

问题描述 投票:0回答:2

来自 ObjectInputStream 的 Javadoc

枚举常量的反序列化与普通可序列化不同 或可外部化的对象。枚举常量的序列化形式 仅由其名称组成;常量的字段值不是 传送。为了反序列化枚举常量,ObjectInputStream 读取 流中的常量名称;反序列化的常量是 通过调用静态方法 Enum.valueOf(Class, String) 获得 枚举常量的基本类型和接收到的常量名称为 论据。与其他可序列化或可外部化的对象一样,枚举 常量可以作为出现的反向引用的目标 随后在序列化流中。枚举的过程 常量被反序列化不能自定义:任何特定于类的 枚举定义的 readObject、readObjectNoData 和 readResolve 方法 反序列化期间类型将被忽略。同样,任何 SerialPersistentFields 或serialVersionUID 字段声明也是 忽略——所有枚举类型都有固定的serialVersionUID 0L。

为什么 Java 中的枚举没有完全序列化? Java 中的枚举不仅仅是常量,而且是还可以包含状态的成熟类。这不会导致发送端和接收端状态不一致吗?我在这里缺少的基本点是什么?

java serialization enums
2个回答
7
投票

教训是当您需要可变对象时不要使用枚举。是的,您可以设计维护内部状态的枚举,但它们并不是为此而设计的。与序列化的情况一样,如果您这样做,并非 Java 的所有部分都会合作。

如果必须将

enum
值与状态数据联系起来,请使用
EnumMap
。该类实现了
Serializable
,因此您不需要执行任何额外的工作来序列化状态数据(假设状态数据对象本身是可序列化的)。


0
投票

对于那些寻找答案的人。这是序列化反序列化枚举类型以进行传输的方式:

只需像这样定义你的枚举:

public enum MyEnum
{
    VAL1("VAL1"),
    VAL2("VAL2");

    private final String value;

    private MyEnum()
    {
        this.value = this.name();
    }

    private MyEnum(final String val)
    {
        this.value = val;
    }

    public String getValue()
    {
        return value;
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.