Effective Java -- 用私有构造器或者枚举类型强化Singleton属性
来源:互联网 发布:淘宝运营实训课教案 编辑:程序博客网 时间:2024/06/06 05:25
本文是 《Effective Java》第三条的读书笔记,由于是Java进阶书,难免会有理解的偏差,如有错误,非常欢迎能批评指正,本人不胜感激!
首先介绍两种常见的实现Singleton
的方法
在这两个方法中,都需要把构造函数设置为私有private
的,并导出该类的公有静态成员。
第一种方法中,公有静态成员是该类的实例(并且是final的),如下
class UserInfo{ public static final UserInfo userInfo = new UserInfo(); private UserInfo(){ // 用户通过反射机制再次创建实例,则抛异常(先不用理解,后面有说到) if(UserInfo.userInfo!=null){ throw new RuntimeException("不能创建多个对象"); } }}
这样在客户端直接通过如下代码即可获取实例(单例的)
UserInfo userInfo=UserInfo.userInfo;
第二种方法中,公有的成员是静态工厂方法,该方法返回该类的静态的final的实例,如下
class UserInfo{ private static final UserInfo userInfo = new UserInfo(); private UserInfo(){ // 用户通过反射机制再次创建实例,则抛异常(先不用理解,后面有说到) if(UserInfo.userInfo!=null){ throw new RuntimeException("不能创建多个对象"); } } public static UserInfo getInstance(){ return UserInfo.userInfo; }}
客户端的代码如下
UserInfo userInfo=UserInfo.getInstance();
但是上面的两个方法都会存在一个问题,如果我们通过Java的反射机制调用私有构造器则就会生成两个实例了
如果该构造函数被调用超过一次,我们可以在该对象的构造函数中抛出异常,如上面构造函数中的代码
if(UserInfo.userInfo!=null){ throw new RuntimeException("不能创建多个对象"); }
我们利用Java反射机制来测试一下
package com.blog.effective3;import java.lang.reflect.Constructor;/** * @func 用私有构造器或者枚举类型强化Singleton属性. * @author 张俊强~ * @time 2017/10/30 21:00 */public class EffectiveJavaDemoOne { public static void main(String[] args) throws Exception{ UserInfo userInfo=UserInfo.userInfo; System.out.println(userInfo); // 第利用反射机制调用私有构造函数 Class<?> class1 = Class.forName("com.blog.effective3.UserInfo"); // 得到构造函数 Constructor con = class1.getDeclaredConstructor(); con.setAccessible(true); UserInfo userInfo1=(UserInfo) con.newInstance();//再次创建一个实例 }}class UserInfo{ public static final UserInfo userInfo = new UserInfo(); private UserInfo(){ // 用户通过反射机制再次创建实例,则抛异常 if(UserInfo.userInfo!=null){ throw new RuntimeException("不能创建多个对象"); } }}
代码抛出如下异常
Caused by: java.lang.RuntimeException: 不能创建多个对象 at com.blog.effective3.UserInfo.<init>(EffectiveJavaDemoOne.java:33) ... 10 more
实现Singleton
的第三种方法这时候就登场了
其表现形式更加的简洁,无偿的提供了序列化机制,绝对的防止了多次实例化。
这种方式就是:单元素的枚举类型——实现Singleton的最佳方法。
enum StudentInfo{ STUDENT_INFO;}
客户端的代码如下
StudentInfo studentInfo=StudentInfo.STUDENT_INFO;
有关该章节中提到的序列化部分,本人了解不是非常的深入,故//TODO 以后再完善相关部分。
参考资料
[1].用私有构造器或者枚举类型强化Singleton属性
2017/10/30 21:58 于福州大学.
阅读全文
1 0
- Effective Java (3) - 用私有构造器或者枚举类型强化Singleton属性
- 《effective java》读书札记第三条用私有构造器或者枚举类型强化Singleton属性
- 用私有构造器或者枚举类型强化singleton属性——Effective Java 读书笔记
- Effective Java 学习 第三条 用私有构造器或者枚举类型强化Singleton属性
- Effective Java 2.3——用私有构造器或者枚举类型强化Singleton属性
- effective java(3) 之用私有构造器或者枚举类型强化Singleton属性
- Effective Java -- 用私有构造器或者枚举类型强化Singleton属性
- Effective Java之用私有构造器或者枚举类型强化Singleton属性(三)
- Effective java第三条:使用私有构造器或者枚举类型强化Singleton属性
- 用私有构造器或者枚举类型强化 Singleton属性
- 用私有构造器或者枚举类型强化Singleton属性
- 用私有构造器或者枚举类型强化Singleton属性
- 用私有构造器或者枚举类型强化Singleton属性。
- 《Effective java》读书记录-第3条-用私有构造器或者枚举类型强化Singleton属性
- Java学习笔记3:用私有构造器或者枚举类型强化Singleton属性
- Java学习笔记3:用私有构造器或者枚举类型强化Singleton属性
- Effective java第三条:用私有构造器或者枚举类型强化singleon属性
- EffectiveJava-用私有构造器或者枚举强化Singleton属性
- Jzoj4845 寻找
- BUG管理
- Python Imaging Library: ImagePath Module(图像路径模块)
- C#程序设计(第二版)-王贤明-清华大学出版社-笔记
- LeetCode112. Path Sum
- Effective Java -- 用私有构造器或者枚举类型强化Singleton属性
- 命令模式-unity实现
- CodeVS 2245 浅谈二维线段树优化间距限制型LCS动态规划状态转移
- C++——【USACO 5.4.2】——Character Recognition
- 解决androiud studio kotlin插件一直提示命名规范的问题
- lvs为何不能完全替代DNS轮询
- 周报汇总-十月
- opencv学习——fft用numpy和cv2
- tensorflow学习之Faster R-CNN模型的保存与加载