Java枚举上的自定义字段未被序列化

7

我有一个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
}

我发现在反序列化后,枚举类型的自定义字段会丢失。

经过更多的了解,我得到的印象是,枚举类型被反序列化为字符串,因此其自定义字段被忽略了。

如果这是真的,那么我是否在滥用枚举类型,应该使用POJO代替?还是有一种方法可以序列化自定义字段(它们不是构造函数的一部分)?

谢谢!


2
使用POJO进行开发。有关“Enum”序列化的信息,请参见此链接:http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/relnotes15.html - nattyddubbs
1
另外一个关于枚举序列化的链接:http://docs.oracle.com/javase/1.5.0/docs/guide/serialization/spec/serial-arch.html#enum - Vladimir Mironov
2个回答

8
如果这些值是恒定不变的,那么这样做更好,并且您不需要对任何内容进行序列化。
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,其中包含这些值以及对枚举值的引用。


1
如果这些字段不需要更改,最好也将它们声明为 final - nattyddubbs
жҲ‘жғізҹҘйҒ“иҝҷз§Қж–№жі•пјҲдҪҝз”ЁsetterпјүжҳҜеҗҰж„Ҹе‘ізқҖеәҸеҲ—еҢ–зҡ„жһҡдёҫе°ҶдёҚеҢ…еҗ«incrementalжҲ–someStrзҡ„жңҖж–°еҖјпјҢиҖҢжҳҜдҪҝз”Ёй»ҳи®ӨеҖјиҝӣиЎҢеәҸеҲ—еҢ–гҖӮ - yshavit
1
它不会保存状态。如果您在枚举外部使用setter,则不应该使用枚举。 - dfb
这是我会假设的,@dfb。根据原始问题,我怀疑这不是OP想要的。如果是的话,OP会提供那个构造函数而不是设置器。 - yshavit
谢谢@dfb。这正是我定义枚举的方式,但现在有一些更改,需要将自定义字段变为可变的。 - Nik S
正如您和@yshavit所讨论的那样,也许我不应该再将它保留为枚举类型了。 - Nik S

7
Java语言规范中可知:

枚举类型中的最终克隆方法确保不能克隆枚举常量,而序列化机制的特殊处理则确保反序列化不会创建重复的实例。禁止通过反射机制实例化枚举类型。这四个限制共同保证了枚举类型不存在除枚举常量以外的任何实例。

如果您的要求将导致创建多个TYPE_A等实例,这将违反枚举的不可变性。请谨慎操作。


它们不必是无状态的,只是不应该具有可变状态。 - yshavit
1
@yshavit - 谢谢;我已经将措辞更改为“不可变的”,以消除任何歧义。 - McDowell
感谢 @McDowell 和 yshavit - 我认为“它们不必是无状态的,只是不应该有可变状态。”可能总结了一切! - Nik S

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接