Java 枚举中的实例

INSTANCE in a Java Enum

在 Enum 中定义 INSTANCE 是一种很好的做法,以便免费进行序列化(有效 Java 第 2 版,第 3 项)。如果有人能再解释一下这是什么意思,那就太好了。

What is the best approach for using an Enum as a singleton in Java?

提前致谢, 林

这是一个演示:

import java.io.*;

class ClassSingleton implements Serializable {
    public static final ClassSingleton INSTANCE = new ClassSingleton();

    private ClassSingleton() {}
}

enum EnumSingleton {
    INSTANCE;
}

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        byte[] data;
        try (ByteArrayOutputStream output = new ByteArrayOutputStream();
             ObjectOutputStream oos = new ObjectOutputStream(output)) {
            oos.writeObject(ClassSingleton.INSTANCE);
            oos.writeObject(EnumSingleton.INSTANCE);
            data = output.toByteArray();
        }

        try (ByteArrayInputStream input = new ByteArrayInputStream(data);
             ObjectInputStream ois = new ObjectInputStream(input)) {
            ClassSingleton first = (ClassSingleton) ois.readObject();
            EnumSingleton second = (EnumSingleton) ois.readObject();

            System.out.println(first == ClassSingleton.INSTANCE);
            System.out.println(second == EnumSingleton.INSTANCE);
        }
    }
}

这里我们既有基于 "simple" class 的单例,也有基于枚举的版本。

我们将两个实例都写到 ObjectOutputStream,然后再次读回。输出是 false 然后是 true,这表明对于基于 class 的单例,我们最终得到了 两个 个实例 ClassSingleton...我们的 "normal" 一个,以及反序列化创建的那个。然而,我们只有一个 EnumSingleton 实例,因为枚举有 serialization/deserialization 代码来保留它们的 "fixed set of values" 性质。您也可以为基于 class 的单例编写此代码,但不必这样做更容易。