为什么我的枚举字段被序列化?

时间:2017-11-15 17:28:59

标签: java serialization enums

根据this document,enum常量'字段未序列化。所以我把以下演示放在一起:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

enum EnumBasedSingleton
{
  INSTANCE;

  EnumBasedSingleton() {
    value = 42;
  }

  int value;

  public int getValue()
  {
    return value;
  }
  public void setValue(int value)
  {
    this.value = value;
  }
}

class EnumBasedSingletonDemo
{
  static void saveToFile(EnumBasedSingleton singleton, String filename)
    throws Exception
  {
    try (FileOutputStream fileOut = new FileOutputStream(filename);
         ObjectOutputStream out = new ObjectOutputStream(fileOut))
    {
      out.writeObject(singleton);
    }
  }

  static EnumBasedSingleton readFromFile(String filename)
    throws Exception
  {
    try (FileInputStream fileIn = new FileInputStream(filename);
         ObjectInputStream in = new ObjectInputStream(fileIn) )
    {
      return (EnumBasedSingleton)in.readObject();
    }
  }

  public static void main(String[] args)
    throws Exception
  {
    EnumBasedSingleton singleton = EnumBasedSingleton.INSTANCE;
    singleton.setValue(111);
    String filename = "myfile.bin";
    saveToFile(singleton, filename);
    EnumBasedSingleton singleton2 = readFromFile(filename);
    System.out.println(singleton2.getValue());
  }
}

我期待输出为42,但我得到的是111。我是误解了这个文件还是枚举常数'字段序列化?我在Java 9中运行它。

1 个答案:

答案 0 :(得分:0)

在java进程的生命周期中,只有一个enum常量的实例。

您链接的文件说明

  

enum常量的序列化形式仅由其名称组成;   常量的字段值不在表单中。要序列化   一个enum常量,ObjectOutputStream写入由...返回的值   enum常量name方法。要反序列化enum常量,   ObjectInputStream从流中读取常量名称;该   然后通过调用,获得反序列化的常量   java.lang.Enum.valueOf方法,传递常量enum类型   将收到的常量名称作为参数。

换句话说,常量名称用于检索适当的实例。但是,该实例与您序列化的实例相同,它不是新实例,enum构造函数未再次调用。由于您之前更改了enum常量的状态,因此您可以看到更改后的值。

如果你开始一个新的java进程并试图在不触及enum常量的情况下反序列化该文件的内容,你会看到它的原始值为42。

误解可能源于在你的枚举中使用可变状态。 That's strongly discouraged.