本文参考

本篇文章参考自《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. .NET Core WebApi使用Swagger

    1.新建Core Api项目,引用Swashbuckle.AspNetCore 包 配置Startup.cs类的 using System; using System.Collections.Gene ...

  2. webrtc学习笔记积累

    https://blog.csdn.net/xyphf/article/details/106536584

  3. 联邦学习:按混合分布划分Non-IID样本

    我们在博文<联邦学习:按病态独立同分布划分Non-IID样本>中学习了联邦学习开山论文[1]中按照病态独立同分布(Pathological Non-IID)划分样本. 在上一篇博文< ...

  4. 微信小程序逐屏分页刷新

    wxml: <view class="page-section-spacing"> <view> <text>商家列表</text> ...

  5. VUE npm run build的项目出现跨域请求的问题npm run dev没有这个问题

    报错信息 Access to XMLHttpRequest at 'http://platformapi-test.lih-elearning.cn/api/v1/login' from origin ...

  6. R-CNN小结

    1.背景 物体检测(object detection)是计算机视觉非常重要的一个领域.RCNN作为该领域的开山鼻祖,在深度学习出现之前,传统方法始终无法处理好物体检测问题(会通过非常庞大的计算,来算出 ...

  7. 用python生成你想要的任意大小文件

    在测试的日常工作中,我们经常会需要测试上传文件的边界值.今天分享一段30行的简单代码,可以生成任意大小的文件,方便测试. file_size=input("请输入想要生成文件的大小:(单位M ...

  8. 报错----运行springboot项目出现:Type javax.xml.bind.JAXBContext not present

    目的:运行springboot项目出现:Type javax.xml.bind.JAXBContext not present 环境: 问题:运行springboot项目出现:Type javax.x ...

  9. JavaWeb——Tomcat使用

    官方下载地址:https://tomcat.apache.org/download-90.cgi 选择安装包: 64-bit Windows zip (pgp, sha512) 注:tar.gz后缀的 ...

  10. atoi atof atol

    在c语言中提供了把字符串转化为整数的函数,并没有提供把整数转化为字符串的函数 atoi是标准的库函数 itoa不是标准的库函数(在vs可编译,其它系统中未知) atol把一个字符串转化为long类型 ...