[Effective Java] Item 3: Enforce the singleton property with a private constructor or an enum type

Item 3讲的是:用private constructor或者enum type去强化singleton的属性。

首先,我们来理解一下singleton的概念。

A singleton is imply a class that is instantiated exactly once.

有两种方法可以实现singleton:

方法1

使用private constructor,member是一个final域。

// singleton with public final field
public class Example {
    public static final Example INSTANCE = new Example();
    private Example() {...}

    public void someMethod() {...}
}

方法1的好处在于,组成类的成员的声明很清楚的表明了这个类是一个singleton。

方法2

使用private constructor,member是一个static factory method。

// singleton with static factory
public class Example {
    private static final Example INSTANCE = new Example();    
    private Example() {...}
    public static Example getInstance() {
        return INSTANCE;
    }

    public void someMethod() {...}
}

方法2的好处在于:
1)灵活性:在不改变API的情况下,可以改变成不是singleton。
2)和泛型有关。

方法3 (Java 1.5及之后才可以)

使用包含单个元素的枚举类型。

// enum singleton - the preferred approach
public enum Example {
    INSTANCE;
    
    public void someMethod() {...}
}

方法3功能上与方法1相近,但是更简洁,无偿提供了序列化机制

序列化

在方法1 & 2中,如果想让singleton类变成可序列化的(serializable),只是加上implements Serializable是不够的。必须声明所有实例域都是transient的,并且提供一个readResolve方法。不然,每次反序列化实例时,都会创建一个新的实例。

// readResolve method to preserve singleton property
private Object readResovle() {
    // return the one true Example and let the garbage collector take care of the Example impersonator.
    return INSTANCE;
}

结论

虽然方法3还没有广泛采用,但已经是最佳方法。

你可能感兴趣的:([Effective Java] Item 3: Enforce the singleton property with a private constructor or an enum type)