Effective Java —— 用私有构造器或枚举类型强化单例属性
本文参考
本篇文章参考自《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 —— 用私有构造器或枚举类型强化单例属性的更多相关文章
- 《Effective Java》-——用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统.使类成为Singleton会使它的客户端测试变得十分困难,因为无法给Si ...
- 用私有构造器或枚举类型强化Singleton
Singleton指只有一个实例的类,只能被创建一次. 在Java1.5之前实现Singleton有两种方式,都是将构造器设为private并导出公有的静态成员实例. 第一种方式将公有的静态成员实例设 ...
- 《effective java》读书札记第三条用私有构造器或者枚举类型强化Singleton属性
Singleton指只被实例化一次的类.一般用来搞那些创建很耗资源或者要求系统中只能有一个实例的类. 这个很经常使用.记得曾经实习面试的时候就有这个面试题. 一般採用的方法是将构造器私有化,然后提供一 ...
- Effective Java 之 --- 用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类,通常用来代表那些本质上唯一的系统组件,实现Singleton有三种方法: 1)公有静态成员是个final域,享有特权的用户可以调用AccessibleObje ...
- 【读书笔记 - Effective Java】03. 用私有构造器或者枚举类型强化Singleton属性
实现Singleton(代表本质上唯一的系统组件)的三种方法: 1. 保持私有构造器,导出公有的静态成员,客户端访问该类的唯一实例. 2. 保持私有构造器,公有的成员是静态工厂方法. 3. 单元素的枚 ...
- 创建和销毁对象——用私有构造器或者枚举类型强化Singleton属性
参考资料:<Effective Java>.<Java核心技术 卷1>.https://www.cnblogs.com/zhaosq/p/10135362.html 基础回顾 ...
- 用私有构造器或者枚举类型强化Singleton属性
1.Singleton指仅仅被实例化一次的类.Singleton通常被用来代表那些本质上唯一的系统组件,如窗口管理器或者文件系统.使类称为Singleton会使它的客户端调试变的十分困难,因为无法给S ...
- 第3条:用私有构造器或者枚举类型强化Singleton属性
Singleton是指仅仅被实例化一次的类.通过被用来代表那些本质上唯一的系统组件,比如窗口管理器或者文件系统. 在http://www.cnblogs.com/13jhzeng/p/5256424. ...
- 第3项:用私有构造器或者枚举类型强化Singleton属性
Singleton指仅仅被实例化一次的类 [Gamma95].Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件.使类称为Singleton会使它的客户端测试变得 ...
随机推荐
- 【C#IO 操作】字符流(StreamWriter、StreamReader)
StreamWaiter类和StreamReader类的用法 事实上, StreamReader为了性能的考虑, 在自己的内部内置并维护了一个byte buffer. 如果在声明StreamReade ...
- Activity的创建及生命周期
- SHA算法(及示例)演变历史
安全散列算法(英语:Secure Hash Algorithm,缩写为SHA)是一个密码散列函数家族,是FIPS所认证的安全散列算法.能计算出一个数字消息所对应到的,长度固定的字符串(又称消息摘要)的 ...
- java中如何将嵌套循环性能提高500倍
java中如何将嵌套循环性能提高500倍 转载请注明出处https://www.cnblogs.com/funnyzpc/p/15975882.html 前面 似乎上一次更新在遥远的九月份,按照既定的 ...
- oauth2.0密码模式详解
oauth2.0密码模式 欢迎关注博主公众号「Java大师」, 专注于分享Java领域干货文章http://www.javaman.cn/sb2/oauth-password 如果你高度信任某个应用, ...
- php 和微信小程序 解构赋值
php 解构赋值只能解构索引数组 js:
- tp5 单文件上传接口
路由: Route::post('upload','task/task/upload'); 控制器代码: //文件上传接口 public function upload() { $file = req ...
- 2022年官网下安装Logstash最全版与官网查阅方法(8.1.0最新安装)
一.环境整合 构建工具(参考工具部署方式) 软件名称 版本 相关文章推荐 NodeJS 16.0.0 https://www.cnblogs.com/liuyangfirst/p/15998172.h ...
- 040_Eureka 服务注册与发现
目录 什么是Eureka 原理讲解 Eureka的基本架构 三大角色 盘点目前工程状况 创建Eureka服务端子模块 springcloud-eureka-7001 导入依赖 pom.xml 配置文件 ...
- Mybatis的ResultMap对column和property
首先,先看看这张图,看能不能一下看明白: select元素有很多属性(这里说用的比较多的): id:命名空间唯一标识,可以被用来引用这条语句 parameterType:将会传入这条语句的参数类的 ...