Item 3: Enforce the singleton property with a private constructor or an enum

1.    Making a class a singleton can make it difficult to test its clients, as it’s impossible to substitute a mock implementation for a singleton unless it implements an interface that serves as its type.


2.    A privileged client can invoke the private constructor reflectively with the aid of the AccessibleObject.setAccessible method. If you need to defend against this attack, modify the constructor to make it throw an exception if it’s asked to create a second instance.

 

3.    To make a singleton class (not implemented as enum) serializable, it is not sufficient merely to add implements Serializable to its declaration. To maintain the singleton guarantee, you have to declare all instance fields transient and provide a readResolve method. Otherwise, each time a serialized instance is deserialized, a new instance will be created:

// 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;
}

commented by Sean: I don't think we should just make all fields transient, because singleton doesn't mean immutable, we may recover singleton's fields from serialization, otherwise it doesn't make sense to make the singleton serializable.

 

4.    As of release 1.5, there is a third approach to implementing singletons. Simply make an enum type with one element. Besides that it is more concise, it provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks. A single-element enum type is the best way to implement a singleton.

你可能感兴趣的:(enum,Singleton,Effective Java)