第三条:使用私有构造器或者枚举类型强化Singleton属性
1, Singleton指的是只能被实例化一次的类。
2, 实现Singleton有3中方法,分别是:
A public class Elvis{ public static final Elvis INSTANCE=new Elvis(); private Elivs(){…} public void othermethod(){…} } B public class Elvis{ public static final Elvis INSTANCE=new Elvis(); private Elivs(){…} public static Elvis getInstance(){return INSTANCE} public void othermethod(){…} } C Public enum Elvis{ INSTANCE; public void othermethod(){…} }
我们可以看到a,b两个方法都是把构造方法私有化了,然后分别通过静态域去实例化。这样做的好处是可以保证客户端能够访问该类的唯一实例。但是要提醒一点,客户端可以借助AccessibleOject.setAccessible方法,通过反射机制去访问私有的构造方法,如果要防御这样的攻击,可以在私有构造方法被要求创建第二个的时候抛出异常。
在b的方法是通过静态工厂去实例化的。其优势在于提供了灵活性。工厂方法返回该类的唯一实例,但是也可以容易的被修改。第二个优势和泛型有关。
3, 为了使用这其中(a,b)一种方法实现的Singleton类变成可序列化的(Serializable)仅仅加上implement Serializable是不够的。为了保证Singleton,必须声明所有实例域是瞬时(transient)的,并提供一个readResolve方法,否则当在反序列化一个序列化的时候,会创建一个新的对象导致出现假冒的现象。
4, C方法是实现Singleton的最佳方法,因为他在功能上合公有域方法(a)相近,但更加简洁,提供了序列化机制,绝对防止多次实例化,即使是在面对复杂的序列化或者反射攻击的时候。