这里有一种优雅的单例写法,采用内部类来创建实例,跟懒汉式一样,只有在调用的时候才进行创建实例
public class LazyStaticInnerSingletion {
private LazyStaticInnerSingletion(){
}
public static LazyStaticInnerSingletion getInstance(){
return InnerHolder.INSTANCE ;
}
private static class InnerHolder{
private static LazyStaticInnerSingletion INSTANCE = new LazyStaticInnerSingletion();
}
}
优点:代码优美,性能高,避免内存浪费
到目前,一共讲了4种单例写法,它们是否存在问题? 它们的单例模式是否能被破坏,如何破坏?
之前讲的写法都可以通过反射破坏
新建测试类:
public class Test {
public static void main(String[] args) {
try {
Class<?> c = LazyStaticInnerSingletion.class;
Constructor constructor = c.getDeclaredConstructor(null);
constructor.setAccessible(true);
Object c1 = constructor.newInstance();
Object c2 = constructor.newInstance();
System.out.println(c1);
System.out.println(c2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过测试可以实例多个对象,那代码如何改进呢?既然反射通过构造函数来实例化对象,那就可以在构造函数里面进行判断
public class LazyStaticInnerSingletion {
private LazyStaticInnerSingletion(){
try {
if(InnerHolder.INSTANCE != null){
throw new RuntimeException("不允许创建");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static LazyStaticInnerSingletion getInstance(){
return InnerHolder.INSTANCE ;
}
private static class InnerHolder{
private static LazyStaticInnerSingletion INSTANCE = new LazyStaticInnerSingletion();
}
}
修改后虽然避免了反射破坏单例,但代码又不优雅,下章继续改进