【问题标题】:Serializing ENUM Singleton序列化 ENUM 单例
【发布时间】:2010-01-28 07:11:36
【问题描述】:

我正在尝试将一个 ENUM 单例实例(如 Joshua Bloch 在他的《Effective Java》一书中所述)序列化到一个文件中。 ENUM 实例是一个简单的 JavaBean,如下所示:

public enum ElvisFan implements Serializable{
  INSTANCE;
  private int totalSongsListened;

private ElvisFan(){
     totalSongsListened=0;
}

public void set(int v){
     totalSongsListened=v;
}

public int get(){
     return totalSongsListened;
}

}
}

我在整个程序中都成功地使用了这个枚举,但是当我使用snakeyaml 将此枚举写入文件时,我的test.yaml 文件中只有!!com.chown.ElvisFan 'INSTANCE'。这就是我正在做的:

Yaml yaml = new Yaml();
yaml.dump(ElvisFan.INSTANCE, new FileWriter("test.yml");

我也试过了,没有运气:

JavaBeanDumper dumper = new JavaBeanDumper();
dumper.dump(ElvisFan.INSTANCE, new FileWriter("test.yml");

有人可以指导我吗?谢谢!

[已编辑]

代码更正。

【问题讨论】:

  • 枚举不应该有状态。而且您的枚举中只有一个值。似乎您使用了错误的工具来完成这项工作。你不只是想要一个普通的单身人士(一个班级)吗?你就不能不使用单例吗?
  • 你是对的。我同意枚举应该是无状态的,但我只是试一试,看看我是否偶然发现了这种枚举,序列化文件的方法可能是什么。请注意,我不是以“这是一个好的设计实践”的方式来问这个问题的。我只是在问“我该怎么做?”将这个类转换为非枚举单例类并不难,所以总的来说它归结为:如果你得到一个这样的类,你将如何写入文件?
  • SnakeYAML 将枚举视为标量。 (除非你强制它使用 JavaBeanDumper 中的映射节点)你必须提供一个自定义的 Representer 来将这种不寻常的枚举转储为 JavaBean。

标签: java file serialization snakeyaml


【解决方案1】:

单身人士没有任何意义。可序列化的单例就更没有意义了。根据定义,只有一个单例。所以当你反序列化一个单例时,你不会得到一个新对象。您将获得具有相同旧数据的相同旧实例。

枚举序列化被特殊处理。它们由名称和类型表示。没有保存其他状态,因为如前所述,这没有任何意义。

我建议修改您的代码以避免可变静态。

枚举不应具有可变状态。使用单个实例序列化枚举在它们实现一些其他类(例如 Comparator)或用作键或类似的情况下是有意义的。

【讨论】:

  • 这就是我需要达到的目标 - 相同的旧数据和相同的旧实例。我很确定可以保存数据,因为snakeyaml 文档提供了一个关于转储/加载枚举数据的类似示例:code.google.com/p/snakeyaml/wiki/Documentation#Enum
  • 哪个旧实例?存在的旧实例,或实际上不以序列化形式存在的旧“实例”。
【解决方案2】:

SnakeYAML 将 List 视为序列而不是映射,即使 List 也有 getter (getFirst())。 为什么你期望 enum 被序列化为 map ?

您必须提供一个自定义的 Representer 来将这种不寻常的枚举转储为 JavaBean。 测试包含大量如何编写自定义 Representer/Constructor 的示例。

【讨论】:

    猜你喜欢
    • 2014-06-06
    • 2018-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多