java 1.5之前
方法1 私有构造器,公有静态final域
public class Elvis(){
public static final Elvis INSTANCE = new Elvis();
private Elvis(){}
public void leaveTheBuilding(){}
}
缺点:享有特权的客户端可以通过AccessibleObject.setAccessible方法,通过反射机制调用构造器。
解决:修改构造器,让它被要求创建第二个实例时抛出异常。
方法2 私有构造器,私有公有静态final域,公有静态工厂方法。
public class Elvis(){
private static final Elvis INSTANCE = new Elvis();
private Elvis(){}
public static Elvis getInstance(){ return INSTANCE;}
public void leaveTheBuilding(){}
}
缺点:每次被反序列化一个序列化的实例时,都会创建一个新的实例。
解决:实现Serializable接口,申明所有实例域都是瞬时(transient)的,提供readResolve方法。
Java1.5后
方法3 单元素的枚举类型
public enum Elvis{
INSTANCE;
public void leaveTheBuilding(){}
}
优点:功能上与公有域方法接近,无偿提供序列化机制,绝对防止多次实例化。