It is a good practices to define INSTANCE in an Enum, for the benefit of serialization for free (Effective Java Edition 2, Item 3). If anyone could explain a bit more what it means, it will be great.
What is the best approach for using an Enum as a singleton in Java?
thanks in advance, Lin
Here's a demonstration:
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);
}
}
}
Here we have both a "simple" class-based singleton, and the enum-based version.
We write out both instances to an ObjectOutputStream
, then read them back again. The output is false
then true
, showing that with the class-based singleton, we've ended up with two instances of ClassSingleton
... our "normal" one, and the one created by deserialization. We only have one instance of EnumSingleton
however, because enums have serialization/deserialization code to preserve their "fixed set of values" nature. You can write this code for the class-based singleton too, but it's easier not to have to.
See more on this question at Stackoverflow