本文参考

本篇文章参考自《Effective Java》第三版第三条"Enforce the singleton property with a private constructor or an enum type"

原文的不足之处

原文给的示例代码比较简单,提供的是一种饿汉式的单例模式

// Singleton with public final field
public class Elvis {
    public static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    public void leaveTheBuilding() { ... }
}

我们也可以将INSTANCE实例的pulice改为private,通过另一个静态方法获取实例

// Singleton with static factory
public class Elvis {
    private static final Elvis INSTANCE = new Elvis();
    private Elvis() { ... }
    public static Elvis getInstance() { return INSTANCE; }
    public void leaveTheBuilding() { ... }
}

构造器的private关键字修饰使得无法通过new关键字创建其它实例,final关键字的修饰使得INSTANCE总是包含相同的对象引用,这两种写法都能保证全局下仅有一个Elvis类的实例化对象

因为饿汉模式下,全局的单例实例在类装载时就进行构建,可能由于初始化的太早,会造成资源的浪费,所以有另一种懒汉式的单例模式,但原文中未做介绍,因为它在多线程下存在实例重复构建的问题,若要解决这个问题,会加大文章篇幅,而且也不是第三条建议的重点,更多关于懒汉式的单例模式可以参考这篇文章:

https://www.jianshu.com/p/eb30a388c5fc

the best way to implement a singleton —— a single-element enum type

Java的枚举类型是一个特殊的class,并继承了Enum<T>类,若Singleton必须扩展一个超类,而不是扩展Enum 时,则不宜使用如下方法

public class Elvis {

  private Elvis() {
  }

  public static Elvis getInstance() {

    return Singleton.INSTANCE.getInstance();
  }

  /**
   *
注意声明为private
   */

  private enum
Singleton {

    INSTANCE;

    private Elvis singleton;

    /**
     *
仅执行一次

     */

    Singleton() {

      singleton = new Elvis();
    }

    public Elvis getInstance() {

      return singleton;
    }
  }
}

因为Enum<T>类实现了Serializable接口,所以为INSTANCE自动提供了序列化机制,并且编译器会为枚举类型的实例自动添加 public static final 修饰,所以枚举类型的无参构造方法仅会被执行一次

原文也指出这种方式能够应对复杂的序列化或者反射攻击的情形

provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks.

最新文章

  1. inner join on 和 where = 的区别!
  2. iOS 笔记
  3. Nginx SPDY缓冲区溢出漏洞
  4. zedboard--Opencv移植和zedboard测试(十一)
  5. BNU 4067 求圆并
  6. ELK日志管理搭建
  7. 【shell脚本】nginx每天自动切割日志脚本
  8. DCOS实践分享(4):如何基于DC/OS整合SMACK(Spark, Mesos, Akka, Cassandra, Kafka)
  9. [GIT] 更新.repo目录
  10. 数据库设计理论与实践&#183;&lt;五&gt;常见疑难杂症
  11. iOS - 集成高德SDK解决Marker点重复点击无效问题
  12. Server.Transfer VS Response.Redirect – Simplified
  13. 虚拟机性能监控与故障处理工具------JDK的命令行工具
  14. PythonWEB框架之Flask
  15. STL 的 vector 根据元素的值来删除元素的方法
  16. 20155234 exp4 恶意代码分析
  17. 网络性能测试工具iperf
  18. 本地搭建https服务
  19. Linux改变文件所有者
  20. Spring Boot中自动执行sql脚本

热门文章

  1. 详解 c# 克隆
  2. HarmonyOS方舟开发框架容器类API的介绍与使用
  3. Python程序基本知识
  4. 关于Union和 Union all,以及出现 ORA-12704:字符集不匹配问题
  5. Phoenix使用
  6. 2W字长文吐血整理 Docker&amp;云原生
  7. http1.1与http2.0
  8. laravel 根据字段不同值做不同查询
  9. ubuntu 学习中的坑-2021-11-22
  10. CF498B题解