【问题标题】:Custom fields on java enum not getting serializedjava枚举上的自定义字段没有被序列化
【发布时间】:2013-03-09 21:33:27
【问题描述】:

我有一个如下所示的 Java 枚举:

public enum ExecutionMode {
  TYPE_A,
  TYPE_B,
  TYPE_C;

  private ExecutionMode(){} //no args constr- no really required

  private boolean incremental; //has get/set
  private String someStr;      //has get/set
}

我看到反序列化后,枚举上的自定义字段丢失了。 在阅读更多关于它的信息时,我的印象是 enum 被反序列化为字符串,因此它的自定义字段被忽略了。

如果它是真的,我是否在这里滥用 Enum 并且应该只使用 POJO 代替? 或者有没有办法序列化自定义字段(不是构造函数的一部分)?

谢谢!

【问题讨论】:

标签: java serialization enums custom-fields


【解决方案1】:

来自Java language specification

枚举中的最终克隆方法确保枚举常量永远不会 被克隆,并且被序列化机制的特殊处理 确保不会因为以下原因而创建重复的实例 反序列化。禁止枚举类型的反射实例化。 这四件事一起确保没有枚举类型的实例 存在超出枚举常量定义的范围。

您所要求的将创建多个实例,例如 TYPE_A。这会破坏枚举。枚举应该是不可变的。

【讨论】:

  • 它们不必是无状态的,它们只是不应该具有可变状态。
  • @yshavit - 谢谢;我已将措辞更改为“不可变”以消除歧义。
  • 感谢@McDowell & yshavit - 我认为“他们不必是无状态的,他们只是不应该有可变状态。”大概总结一下吧!
【解决方案2】:

如果值是恒定的,那就更好了,你不需要序列化任何东西

public enum ExecutionMode {
  TYPE_A(x,t),
  TYPE_B(y,z),
  TYPE_C(b,s)

  private boolean incremental; //has get/set
  private String someStr;      //has get/set

  ExecutionMode(boolean incremental,String someStr){
        ///... set things appropriately
  } 
}

如果您在运行时设置这些值,我的倾向是,这首先不应该是一个枚举 - 应该有一个单独的 POJO,它可能包含值以及对枚举值的引用.

【讨论】:

  • 如果不更改这些字段,也可以将这些字段设为final
  • 我想知道这种方法(使用setter)是否意味着序列化的枚举将不包含incrementalsomeStr的最新值,而是使用默认值进行序列化。
  • @yshavit - 它不会保持状态。如果您在枚举之外使用 setter,则它不应该是枚举。
  • 这就是我的假设,@dfb。根据最初的问题,我怀疑这不是 OP 想要的。如果是,则 OP 将提供该构造函数并且没有设置器。
  • 谢谢@dfb。这正是我定义枚举的方式,但现在有一些变化是必须使自定义字段可变。
猜你喜欢
  • 2014-08-10
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 2021-05-11
  • 2022-07-06
相关资源
最近更新 更多