Effective Java学习笔记之一
今天开始系统看《Effective Java》,将看书的细节记下备忘,并不是总结。
很早开始就接触到设计模式,特别是最简单的单例模式,Java实现单例模式,我开始的思路是设置一个私有静态类实例化变量,初值设为null,提供一个静态初始化的get方法,if判断变量是否为null选择是否new一个实例。代码如下:
public class ClassicSingleton { private static ClassicSingleton instance = null; protected ClassicSingleton() { } public static ClassicSingleton getInstance() { if(instance == null) { instance = new ClassicSingleton(); } return instance; } }
但是很快看到别人提出这个代码的问题,它不是线程安全的,也就是说在多线程情况下,在if(instance == null)这段代码处切换,导致重复调用会实例化多个不同的实例。开始想不就是个同步吗,只需要加个关键字synchronized在方法getInstance就行了。又涉及到效率问题。
又提出一种改进声明成公共的final变量,同时由于构造器是似有的确保了唯一性。代码如下:
package singleton.implement; public class Singleton1 { public static final Singleton1 INSTANCE = new Singleton1(); private Singleton1() { } }
但存在反射机制攻击问题
再有就是静态工厂方法,代码如下:
package singleton.implement; public class Singleton2 { private static final Singleton2 INSTANCE = new Singleton2(); private Singleton2() { } public static Singleton2 getInstance() { return INSTANCE; } }
还有就是序列化问题。如果定义的类实现了Serializable接口,在反序列话时会有多个实例生成的问题,需要加readResolve方法
import java.io.Serializable; public class Singleton2 implements Serializable{ private static final Singleton2 INSTANCE = new Singleton2(); private Singleton2() { } public static Singleton2 getInstance() { return INSTANCE; } private Object readResolve() { return INSTANCE; } }
最后实现最简单的方法也是最好的是枚举,代码如下:
public enum Singleton3 { INSTANCE; public void leaveTheBuilding() { } }