用私有构造器或者枚举类型强化SingleTon(单例)属性
单例(singleton)就是一个只实例化一次的类。使类成为单例可能会使它的测试变得困难,因为除非它实现了作为其类型的接口,否则不可能用模拟实现来代替这个单例。下面是几种实现单例的方法:
1、共有静态成员是final类型
// Singleton with public final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
}
私有构造器之后执行一次,实例化Elvis.INSTANCE属性,由于缺少公有(public)的或者受保护(protected)的构造器,所以Elvis一旦被实例化,就只会存在一个Elvis的实例(注:反射是可以实现多次调用私有的构造器,若需要抵御这种攻击,则可以修改私有构造器,让它在被创建第二个实例时,抛出异常,或直接返回第一个实例对象)。
2、公有的成员是一个静态方法。
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() { ... }
public static Elvis getInstance() { return INSTANCE; }
}
这个方式可以通过公有静态方法将类改为非单例,但用户代码不需要改变。
为了使利用这其中一种方法实现的SingleTon类变成是可序列化的(Serializable),仅仅在申明上加上“implements Serializable”是不够的。为了维护并保证SingleTon,必须申明所有实例都是瞬时的(transient),并提供一个readResolve方法,否者,每次反序列化一个序列化的实例时,都会创建一个新的实例,比如说,在我们的实例中,会导致“假冒的Elvis”。为了防止这种情况,要在Elvis类中加入下面这个readResolve方法:
参考地址:https://blog.csdn.net/zhushuai1221/article/details/51780895
//1、防止反序列化获取多个对象的漏洞。
//2、无论是实现Serializable接口,或是Externalizable接口,当从I/O流中读取对象时,readResolve()方法都会被调用到。
//3、实际上就是用readResolve()中返回的对象直接替换在反序列化过程中创建的对象。
private Object readResolve(){
return INSTANCE;
}
3、使用枚举实现单例(最佳方式)
/**
* 使用枚举的单例模式
*
*/
public class Elvis{
private Elvis(){}
public static Elvis getInstance(){
return Singleton.INSTANCE.getInstance();
} private enum Singleton{
INSTANCE; private Elvis singleton;
//JVM会保证此方法绝对只调用一次
Singleton(){
singleton = new Elvis();
}
public Elvis getInstance(){
return singleton;
}
}
}
这种方法是在需要的类中编写一个包含单个元素的枚举类型。无偿的提供了序列化机制,绝对防止多次序列化,即使是在面对复杂的序列化或者反射攻击的时候。
用私有构造器或者枚举类型强化SingleTon(单例)属性的更多相关文章
- 《Effective Java》-——用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统.使类成为Singleton会使它的客户端测试变得十分困难,因为无法给Si ...
- 《effective java》读书札记第三条用私有构造器或者枚举类型强化Singleton属性
Singleton指只被实例化一次的类.一般用来搞那些创建很耗资源或者要求系统中只能有一个实例的类. 这个很经常使用.记得曾经实习面试的时候就有这个面试题. 一般採用的方法是将构造器私有化,然后提供一 ...
- Effective Java 之 --- 用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类,通常用来代表那些本质上唯一的系统组件,实现Singleton有三种方法: 1)公有静态成员是个final域,享有特权的用户可以调用AccessibleObje ...
- 【读书笔记 - Effective Java】03. 用私有构造器或者枚举类型强化Singleton属性
实现Singleton(代表本质上唯一的系统组件)的三种方法: 1. 保持私有构造器,导出公有的静态成员,客户端访问该类的唯一实例. 2. 保持私有构造器,公有的成员是静态工厂方法. 3. 单元素的枚 ...
- 第3项:用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类 [Gamma95].Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件.使类称为Singleton会使它的客户端测试变得 ...
- 用私有构造器或者枚举类型强化Singleton属性
1.Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,如窗口管理器或者文件系统.使类称为Singleton会使它的客户端调试变的十分困难,因为无法给S ...
- 用私有构造器或枚举类型强化Singleton
Singleton指只有一个实例的类,只能被创建一次. 在Java1.5之前实现Singleton有两种方式,都是将构造器设为private并导出公有的静态成员实例. 第一种方式将公有的静态成员实例设 ...
- 创建和销毁对象——用私有构造器或者枚举类型强化Singleton属性
参考资料:<Effective Java>.<Java核心技术 卷1>.https://www.cnblogs.com/zhaosq/p/10135362.html 基础回顾 ...
- 第3条:用私有构造器或者枚举类型强化Singleton属性
Singleton是指仅仅被实例化一次的类.通过被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统. 在http://www.cnblogs.com/13jhzeng/p/5256424. ...
随机推荐
- Echarts 折线类型
1:Echarts2.0 这种皮肤下柱状图转折线图默认是平滑曲线 默认皮肤为硬折线: 如果需要在2.0的macarons皮肤下使用硬折线需显式设置以下属性: series: [ { ...
- javascript实现下拉菜单的显示与隐藏
demo.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- python模块之numpy,pandas基本用法
numpy: 是 Python 的一个扩展程序库,支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库简单来说:就是支持一维数组和多维数组的创建和操作,并有丰富的函数库. 直接看例子 ...
- Jenkins之配置GitHub-Webhook2
什么是持续集成(Continuous integration) 提出者Martin Fowler本人对持续集成是这样定义的:持续集成是一种软件开发实践,即团队开发成员经常集成他们的工作,通常每个成员每 ...
- mybatis整合redis二级缓存
mybatis默认开启了二级缓存功能,在mybatis主配置文件中,将cacheEnabled设置成false,则会关闭二级缓存功能 <settings> <!--二级缓存默认开启, ...
- JMeter简单使用
JMeter是apache公司基于java开发的一款开源压力测试工具.因为它是java开发的,所以运行的时候必须要安装jdk才可以:Jmeter是免安装的,所以拿到安装包后直接解压就可以使用了,它也是 ...
- .Net Core 使用Redis进行数据缓存
1.运行环境 开发工具:Visual Studio 2017 JDK版本:.NET Core 2.0 项目管理工具:nuget 2.GITHUB地址 https://github.com/nbfujx ...
- php strncmp()函数 语法
php strncmp()函数 语法 作用:比较字符串前n个字符,区分大小写 语法:strncmp(string1,string2,length)直线电机品牌 参数: 参数 描述 string1 必须 ...
- webpack对脚本和样式的处理
一.对js处理 webpack本身支持js加载也可以用插件. 1.加载要全局使用的插件比如jquery 在页面用cdn方式引用,然后再webpack.config.js里配置.会让jquery成为全局 ...
- 攻防世界 WEB篇
0x01 ics-06 查看源码发现:index.php 一开始直接用sqlmap跑了下没有发现注入,然后用brupsuite爆破参数 0x02 NewsCenter SQL注入中的POST注入,查阅 ...