文档章节

单例模式

wuyiyi
 wuyiyi
发布于 11/19 16:34
字数 361
阅读 10
收藏 0
  • 第一种方式
public class SingletonA {
    public static final SingletonA INSTANCE = new SingletonA();

    private SingletonA(){
        //do something
    }
}
  • 第二种方式
public class SingletonB {
    private static final SingletonB INSTANCE = new SingletonB();

    private SingletonB(){
        //do something
    }
    public static SingletonB getInstance(){
        return INSTANCE;
    }
}

但是上述两种方式都存在一个问题:享有特权的客户端可以借助AccessibleObject.setAccessible方法,通过反射机制调用私有构造器来实例化多个不同的实例

 @Test
    public void test(){
        SingletonA singletonA = SingletonA.INSTANCE;
        Class<SingletonA> cls = SingletonA.class;
        try {
            Constructor<SingletonA> constructor = cls.getDeclaredConstructor(new Class[]{});
            constructor.setAccessible(true);
            SingletonA singletonA1 = constructor.newInstance(new Object[]{});

            System.out.println(singletonA == singletonA1);  //false
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

在《Effective Java中文版 第2版》一书中指出

从java 1.5发行版本起,实现Singleton还有第三种方法。只需编写一个包含单个元素的枚举类型。这种方法在功能上与公有域方法相近,但是它更简洁,无偿地提供了序列化机制,绝对防止多次实例化,即使在面对复杂的序列化或者反射攻击的时候。虽然这种方法话没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

public class EnumSigleton {

    private EnumSigleton() {
    }

    public static EnumSigleton getInstance() {
        return Singleton.INSTANCE.getInstance();
    }

    private enum Singleton {
        INSTANCE;
        private EnumSigleton enumSigleton;

        //JVM保证这个方法绝对只调用一次
        Singleton() {
            enumSigleton = new EnumSigleton();
        }

        public EnumSigleton getInstance() {
            return enumSigleton;
        }
    }
}

© 著作权归作者所有

共有 人打赏支持
wuyiyi
粉丝 1
博文 49
码字总数 22238
作品 0
浦东
程序员
私信 提问
【设计模式笔记】(十六)- 代理模式

一、简述 代理模式(Proxy Pattern),为其他对象提供一个代理,并由代理对象控制原有对象的引用;也称为委托模式。 其实代理模式无论是在日常开发还是设计模式中,基本随处可见,中介者模式中...

MrTrying
06/24
0
0
设计模式已经陨落了?

你现在是坐在一个程序员旁边吗?如果是的话,那么在你读下面的段落之前,有一个简单的实验。让他们到一边去,问问他们两个问题并记录下答案。首先问他们“什么是设计模式?”然后再问“说出你...

oschina
2014/03/11
9.1K
69
《PHP设计模式大全》系列分享专栏

《PHP设计模式大全》已整理成PDF文档,点击可直接下载至本地查阅 https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第1/3页 php设计模式介绍之值对象模式第1/5页...

kaixin_code
11/06
0
0
设计模式梳理(一)

设计模式梳理(一) 总体来说设计模式分为三大类: @案例源码地址:https://gitlab.com/lxqxsyu/DisgnPattern 创建型模式 简单工厂模式 工厂类是整个模式的关键。它包含必要的判断逻辑,能够...

lxq_xsyu
2017/11/02
0
0
Ubuntu中vi卸载与安装/使用模式

Ubuntu中安装的vi是vim-common版本,与centos系统中vi使用方式不同,编辑使用不惯, 遂卸载重装,卸载命令:sudo apt-get remove vim-common 卸载完毕后重新安装;输入命令:sudo apt-get in...

唐十三郎
11/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

区块链安全 - 以太坊短地址攻击

1 基础知识 EVM虚拟机在解析合约的字节码时,依赖的是ABI的定义,从而去识别各个字段位于字节码的什么地方。关于ABI,可以阅读这个文档: https://github.com/ethereum/wiki/wiki/Ethereum-C...

HiBlock
14分钟前
0
0
自定义函数及内部函数

变量的作用域 局部变量 global $Global及其他超全局数组 静态变量 仅初始化赋值 保留于内存直到response才销毁 global和static变量的区别 global:局部变量全局话 static:定义静态局部变量 函...

关元
15分钟前
0
0

中国龙-扬科
27分钟前
1
0
python包

https://www.lfd.uci.edu/~gohlke/pythonlibs/

陆朋
37分钟前
1
0
一文弄懂“分布式锁”,一直以来你的选择依据正确吗?

本文主要会关注的问题是“分布式锁”的问题。 多线程情况下对共享资源的操作需要加锁,避免数据被写乱,在分布式系统中,这个问题也是存在的,此时就需要一个分布式锁服务。 常见的分布式锁实...

Java干货分享
45分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部