is it possible to serialize a singleton object?
It depends on how the singleton is implemented. If your singleton is implemented as an enum type with one element, then it is by default:
// Enum singleton - the preferred approach
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() { ... }
}
If your singleton is not implemented using a single-element enum type but, say using a static factory method (the variant is to use a public static final field):
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
public void leaveTheBuilding() { ... }
}
Then it is not sufficient to add implements Serializable to make it serializable, you must declare all instance fields transient (to prevent a serialization attack) and provide a readResolve method.
To maintain the singleton guarantee,
you have to declare all instance
fields transient and provide a
readResolve method (Item 77).
Otherwise, each time a serialized
instance is deserialized, a new
instance will be created, leading, in
the case of our example, to spurious
Elvis sightings. To prevent this, add
this readResolve method to the Elvis
class:
// readResolve method to preserve singleton property
private Object readResolve() {
// Return the one true Elvis and let the garbage collector
// take care of the Elvis impersonator.
return INSTANCE;
}
This is heavily discussed in Effective Java (which also shows the serialization attack):
- Item 3: Enforce the singleton property with a private constructor or an enum type
- Item 77: For instance control, prefer enum types to readResolve
in which scenario should we serialize a singleton
For example for temporary, short-term storage or for transporting objects over a network (with RMI, for example).
And is it possible to design a class whose object can not be serialized.
As others said, don't implement Serializable. And even if an object or one of its superclasses implements Serializable, you can still prevent it from being serialized by throwing a NotSerializableException from writeObject().