单例(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(单例)属性的更多相关文章

  1. 《Effective Java》-——用私有构造器或者枚举类型强化Singleton属性

    Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统.使类成为Singleton会使它的客户端测试变得十分困难,因为无法给Si ...

  2. 《effective java》读书札记第三条用私有构造器或者枚举类型强化Singleton属性

    Singleton指只被实例化一次的类.一般用来搞那些创建很耗资源或者要求系统中只能有一个实例的类. 这个很经常使用.记得曾经实习面试的时候就有这个面试题. 一般採用的方法是将构造器私有化,然后提供一 ...

  3. Effective Java 之 --- 用私有构造器或者枚举类型强化Singleton属性

    Singleton指仅仅被实例化一次的类,通常用来代表那些本质上唯一的系统组件,实现Singleton有三种方法: 1)公有静态成员是个final域,享有特权的用户可以调用AccessibleObje ...

  4. 【读书笔记 - Effective Java】03. 用私有构造器或者枚举类型强化Singleton属性

    实现Singleton(代表本质上唯一的系统组件)的三种方法: 1. 保持私有构造器,导出公有的静态成员,客户端访问该类的唯一实例. 2. 保持私有构造器,公有的成员是静态工厂方法. 3. 单元素的枚 ...

  5. 第3项:用私有构造器或者枚举类型强化Singleton属性

      Singleton指仅仅被实例化一次的类 [Gamma95].Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件.使类称为Singleton会使它的客户端测试变得 ...

  6. 用私有构造器或者枚举类型强化Singleton属性

    1.Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,如窗口管理器或者文件系统.使类称为Singleton会使它的客户端调试变的十分困难,因为无法给S ...

  7. 用私有构造器或枚举类型强化Singleton

    Singleton指只有一个实例的类,只能被创建一次. 在Java1.5之前实现Singleton有两种方式,都是将构造器设为private并导出公有的静态成员实例. 第一种方式将公有的静态成员实例设 ...

  8. 创建和销毁对象——用私有构造器或者枚举类型强化Singleton属性

    参考资料:<Effective Java>.<Java核心技术 卷1>.https://www.cnblogs.com/zhaosq/p/10135362.html 基础回顾 ...

  9. 第3条:用私有构造器或者枚举类型强化Singleton属性

    Singleton是指仅仅被实例化一次的类.通过被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统. 在http://www.cnblogs.com/13jhzeng/p/5256424. ...

随机推荐

  1. 【python实例】要求输出字符串中最少一个最多八个的所有字符串组合(连续)

    """ 题目:字符串str="ABCDEFGHIJK",要求输出最少一个最多八个的所有组合(向后连续字母) 输出如下: A [0::] AB ABC ...

  2. 异常 Cannot resolve class or package

    spring boot yml配置异常Cannot resolve class or package 是因为mvaen设置 pom.xml的文件配置如上,scope 范围指定为runtime,runt ...

  3. java连接远程服务器并执行命令

    导入必要的jar包 <dependency>  <groupId>ch.ethz.ganymed</groupId> <artifactId>ganym ...

  4. mobx学习笔记04——mobx常用api

    1 可观察的数据(observable) observable是一种让数据的变化可以被观察的方法. 那些数据可被观察? -原始类型 String.Number.Boolean.Symbol -对象 - ...

  5. boost bimap

    The library Boost.Bimap is based on Boost.MultiIndex and provides a container that can be used immed ...

  6. mybatis框架之装饰模式

    学习开源框架源码,除了储备点知识以便于与面试官互相忽略之外,我想最重要的还是去学习大神如何写代码,如何做到职责单一,如何做到可扩展等... 本篇,试着总结一下mybatis在缓存模块使用到的装饰模式. ...

  7. springmvc把对象放到session中

    1:首先把创建的对象放到Map中, @RequestMapping("/testSession")    public String testSession(Map<Stri ...

  8. NOIP 历年试题大致考点总结

    总的来说,水平还不够-- 要努力了! NOIP2012 D1T1 模拟, 字符串 D1T2 贪心, 数学 (推导贪心策略), 高精度 D1T3 unsolved 开车旅行 倍增 D2T1 解线性模方程 ...

  9. [CSP-S模拟测试]:施工(DP+单调栈+前缀和)

    题目描述 小$Y$家门前有一条街道,街道上顺序排列着$n$幢建筑,其中左起第$i$幢建筑的高度为$h_i$.小$Y$定义街道的不美观度为所有相邻建筑高度差的绝对值之和乘上常数$c$,为了改善街道环境, ...

  10. mysql经典面试题之学生成绩表

    需要数据库表1.学生表 Student(SID,Sname,Sage,Ssex) --SID 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 2.课程表 Course(CID, ...