单例模式四(静态内部类单例)

这里有一种优雅的单例写法,采用内部类来创建实例,跟懒汉式一样,只有在调用的时候才进行创建实例

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();
    }
}

修改后虽然避免了反射破坏单例,但代码又不优雅,下章继续改进 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值