Effective Java - 创建和销毁对象 - 用私有构造器或者枚举类型强化 Singleton 属性

读书笔记 仅供参考

Singleton: 仅被实例化一次的类(单例)。通常用来代表本质上唯一的系统组件。

方法一:公有静态 final 成员(Java 1.5 之前便可以使用)

public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    //私有构造函数
    private Elvis(){ ... }
}

由于缺少公有的或收保护的构造器,保证了 Elvis 的全局唯一性。
可以使用 AccessibleObject.setAccessible 方法,通过反射机制调用私有构造器。可以修改构造器,在被要求创建第二个实例时抛出异常抵御攻击。

方法二:静态工厂方法(Java 1.5 之前便可以使用)

public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    public static Elvis getInstance() {
        return INSTANCE;
    }
}

方法一的缺陷仍然存在。
优势在于:一,提供了灵活性,在不改变 API 的情况下,可以改变该类是否为 Singleton。二,与泛型有关。
为使得上述两种方法实现的 Singleton 类变为可序列化的,加上 “implements Serializable”是不够的,当当反序列化一个实例时,都会创建一个新的实例,所以要加入以下方法。

private Object readResolve(){
    return INSTANCE;
} 

方法三:单元素枚举(Java 1.5 之后才可以使用)

public enum Elvis {
    INSTANCE;
}

这种方法无偿提供了序列化机制。单元素的枚举类型已经成为实现 Singleton 的最佳方法。

ps: 引申到设计模式的单例模式:(懒汉式单例,饿汉式单例,登记式单例)
别人的博客

你可能感兴趣的:(effective-java,读书笔记,java,singleton,effective-java,读书笔记)