本文参考

本篇文章参考自《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.

Effective Java —— 用私有构造器或枚举类型强化单例属性的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. C# 2进制、8进制、10进制、16进制...各种进制转换

    在.NET Framework中,System.Convert类中提供了较为全面的各种类型.数值之间的转换功能. 其中的两个方法可以轻松的实现各种进制的数值间的转换: Convert.ToInt32( ...

  2. 【C# 表达式树 三】ExpressionType 节点类型种类

    // // 摘要: // 描述表达式目录树的节点的节点类型. public enum ExpressionType { // // 摘要: // 加法运算,如 a + b,针对数值操作数,不进行溢出检 ...

  3. 基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2

    基于Kubernetes/K8S构建Jenkins持续集成平台(上)-2 Kubernetes实现Master-Slave分布式构建方案 传统Jenkins的Master-Slave方案的缺陷 Mas ...

  4. LeetCode-022-括号生成

    括号生成 题目描述:数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合. 示例说明请见LeetCode官网. 来源:力扣(LeetCode) 链接:https ...

  5. CSS复合选择器,元素的显示模式,CSS背景设置

    欢迎大家去博客冰山一树Sankey,浏览效果更好.直接右上角搜索该标题即可 博客园主页:博客园主页-冰山一树Sankey CSDN主页:CSDN主页-冰山一树Sankey 前端学习:学习地址:黑马程序 ...

  6. java方法学习

    java方法学习 方法概念 什么是方法 方法就是完成某些事情的过程,如:实现两个数相加,用方法add(数值1,数值2). 1.System.out.print(),System是系统的一个类,out是 ...

  7. 如何实现ARC中weak功能?

    原文链接 我们都知道ARC中weak与assign或者说unsafe_unretained最大的不同就是设置weak属性后,系统会在对象被释放后自动将指向对象的指针置为nil,而assign则会产生一 ...

  8. Nebula Graph 在企查查的应用

    本文首发于 Nebula Graph Community 公众号 背景 企查查是企查查科技有限公司旗下的一款企业信用查询工具,旨在为用户提供快速查询企业工商信息.法院判决信息.关联企业信息.法律诉讼. ...

  9. pd.cut和pd.qcut()之间的区别

  10. Swagger整合Jwt授权配置

    Swagger整合Jwt授权配置 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章http://www.javaman.cn/sb2/swagger-jwt 一.Swagger入门 ...