单例模式,是指一个类只有一个唯一的实例,一个类只会被实例化一次。实现这种效果,最佳的方式,编写包含单个元素的枚举类型。

单例模式的最佳实现方式-----创建一个包含单个元素的枚举类

  1. public enum Elvis {
  2. ONE_INSTANCE;
  3.  
  4. public void leaveTheBuilding() {
  5. System. out.println("Whoa baby, I'm outta here!" );
  6. }
  7.  
  8. }
  9.  
  10. ----------------------------------
  11. public class Test {
  12.  
  13. public static void main(String[] args) {
  14. Elvis elvis = Elvis. ONE_INSTANCE;
  15. elvis.leaveTheBuilding();
  16. }
  17. }
优点就是:无偿提供了序列化机制,绝对防止多次实例化,解决每次反序列化一个实例化时,再次创建一个心的实例的问题;并且处理了发射攻击(用户通过反射机制,调用了私有构造器,从而打破只有一个实例的规定).
缺点:Java 1.5开始才支持。
 
通过一个公有的静态成员来实现--唯一的实例,是一个公有的静态成员
  1. public class Elvis {
  2. public static final Elvis INSTANCE = new Elvis();
  3.  
  4. private Elvis() {
  5. }
  6.  
  7. public void leaveTheBuilding() {
  8. System. out.println("Whoa baby, I'm outta here!" );
  9. }
  10.  
  11. // This code would normally appear outside the class!
  12. public static void main(String[] args) {
  13. Elvis elvis = Elvis. INSTANCE;
  14. elvis.leaveTheBuilding();
  15. }
  16. }
缺点:1.存在反射攻击缺陷。要抵御反射攻击,就要记录创建实例的个数,使用一个静态的类成员来保存。当实例个数超过1时,发出异常。2.在序列化一个类时,要添加方法readResolve。添加该方法的目的是,避免每次在反序列化的时候创建一个新的实例。
优点:它的表现简洁明了。
 
通过公有的静态工厂方法
 
  1. public class Elvis {
  2. private static final Elvis INSTANCE = new Elvis();
  3.  
  4. private Elvis() {
  5. }
  6.  
  7. public static Elvis getInstance() {
  8. return INSTANCE ;
  9. }
  10.  
  11. public void leaveTheBuilding() {
  12. System. out.println("Whoa baby, I'm outta here!" );
  13. }
  14.  
  15. // This code would normally appear outside the class!
  16. public static void main(String[] args) {
  17. Elvis elvis = Elvis. getInstance();
  18. elvis.leaveTheBuilding();
  19. }
  20. }
优点:
将API与实现隔绝开,客户端只管调用getInstance()方法,不管该方法是怎么实现的。如此,你就可以修改getInstance()的实现,而不用考虑客户端是怎么使用的。
比如,它可以被修改为,并不是返回一个唯一的实例;或者修改为,每个线程有一个唯一的实例,在某个线程范围内,该类的实例是唯一的。
 
缺点:
1.存在反射攻击缺陷。要抵御反射攻击,就要记录创建实例的个数,使用一个静态的类成员来保存。当实例个数超过1时,发出异常。
2.在序列化一个类时,要添加方法readResolve。添加该方法的目的是,避免每次在反序列化的时候创建一个新的实例。
解决缺点2的做法:
添加一个readResolve()方法。
  1. public class Elvis implements Serializable {
  2. /**
  3. *
  4. */
  5. private static final long serialVersionUID = 1L;
  6.  
  7. public static final Elvis INSTANCE = new Elvis();
  8.  
  9. private String one;
  10.  
  11. private Elvis() {
  12. }
  13.  
  14. public void leaveTheBuilding() {
  15. System. out.println("Whoa baby, I'm outta here!" );
  16. }
  17.  
  18. private Object readResolve() {
  19. // Return the one true Elvis and let the garbage collector
  20. // take care of the Elvis impersonator.
  21. return INSTANCE ;
  22. }
  23.  
  24. // This code would normally appear outside the class!
  25. public static void main(String[] args) {
  26. Elvis elvis = Elvis. INSTANCE;
  27. elvis.leaveTheBuilding();
  28. }
  29. }

  

 

Item 3 ------单例模式的几种实现方式,及优缺点的更多相关文章

  1. Python中的单例模式的几种实现方式的优缺点及优化

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  2. JAVA中单例模式的几种实现方式

    1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...

  3. Python 单例模式的几种实现方式

    单例模式的几种实现方式 先来看几个魔法方法的简单运用:__new__, __init__, __call__. class A(object): def __init__(self, x): prin ...

  4. Python中的单例模式的几种实现方式的及优化

    单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在.当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场. ...

  5. CSIC_716_20191129【 单例模式 的五种实现方式】

     单例模式 单例模式:在确定类中的属性和方法不变时,需要反复调用该类的情况.  让所有通过该类实例化出的对象,都指向同一个内存地址. 优点:节省内存空间. 单例模式有五种表现形式: 1.通过class ...

  6. js的三种继承方式及其优缺点

    [转] 第一种,prototype的方式: //父类 function person(){ this.hair = 'black'; this.eye = 'black'; this.skin = ' ...

  7. 单例模式的两种实现方式对比:DCL (double check idiom)双重检查 和 lazy initialization holder class(静态内部类)

    首先这两种方式都是延迟初始化机制,就是当要用到的时候再去初始化. 但是Effective Java书中说过:除非绝对必要,否则就不要这么做. 1. DCL (double checked lockin ...

  8. C#单例模式的几种实现方式

     一.多线程不安全方式实现 public sealed class SingleInstance { private static SingleInstance instance; private S ...

  9. 关于单例模式的N种实现方式

    在开发中经常用到单例模式,单例模式也算是设计模式中最容易理解,也是最容易手写代码的模式,所以也常作为面试题来考.所以想总结一下单例模式的理论知识,方便同学们面试使用. 单例模式实现的方式只有两种类型, ...

随机推荐

  1. 1001 Duplicate Pair

    1.题目戳这里 2.代码: #include<stdio.h> #include<string.h> int main() { int n; while(scanf(" ...

  2. 从零讲JAVA ,给你一条 清晰地学习道路!该学什么就学什么!!

    1.计算机基础: 1.1数据机构基础: 主要学习:1.向量,链表,栈,队列和堆,词典.熟悉2.树,二叉搜索树.熟悉3.图,有向图,无向图,基本概念4.二叉搜索A,B,C类熟练,9大排序熟悉.5.树的前 ...

  3. [core python programming]chapter 7 programming MS office

    excel.pyw会有问题,解决如下: 因为python3x中没有tkMessageBox模块,Tkinter改成了tkinter你可以查看你的py当前支持的模块.在交互式命令行下输入>> ...

  4. lintcode-182-删除数字

    182-删除数字 给出一个字符串 A, 表示一个 n 位正整数, 删除其中 k 位数字, 使得剩余的数字仍然按照原来的顺序排列产生一个新的正整数. 找到删除 k 个数字之后的最小正整数. N < ...

  5. RXSwift --UITableView之初探

    对于RXSwift中的一些基本概念和说明请参看其他文章,接下来我们使用RXSwift一步一步去构建TableView,从简单到复杂.iOS开发过程中tableView的使用率是最高的,他的一些代理方法 ...

  6. IIS安装出现“安装程序无法复制文件CONVLOG.EX_”的解决办法

    重新安装了一次IIS,结果就在重新安装的时候,出现安装程序无法复制文件CONVLOG.EX_,上网找了找资料,是因为secedit.sdb 数据库的问题,既然是因为这个文件的问题,那么我们就可以使用w ...

  7. Qt Meta Object system 学习

    原文地址:http://blog.csdn.net/ilvu999/article/details/8049908 使用 meta object system 继承自 QOject 类定义中添加 Q_ ...

  8. name(实例化类名).hbm.xml文件案例

    [html] view plain copy print? <span xmlns="http://www.w3.org/1999/xhtml"><?xml ve ...

  9. matlab读图函数

    最基本的读图函数:imread imread函数的语法并不难,I=imread('D:\fyc-00_1-005.png');其中括号内写图片所在的完整路径(注意路径要用单引号括起来).I代表这个图片 ...

  10. 【bzoj4401】块的计数 结论题

    题目描述 给出一棵n个点的树,求有多少个si使得整棵树可以分为n/si个连通块. 输入 第一行一个正整数N,表示这棵树的结点总数,接下来N-1行,每行两个数字X,Y表示编号为X的结点与编号为Y的结点相 ...