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

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

Singleton指仅仅被实例化一次的类。Singleton通常会被用来本质上唯一的系统组件,比如窗口管理器或者文件系统。使类成为Singleton会使它的客户端测试变得十分困难,因为无法给Singleton替换模拟实现,除非它实现一个充当其类型的借口。

实现Singleton的两种方法,这两种方法都要把构造器保持为私有的,并导出公有的静态成员,以便允许客户端能够访问该类的唯一实例。在第一种方法中,公有静态成员是个final域:

1 //Singleton with public final field
2 public class Elvis {
3     public static final Elvis INSTANCE = new Elvis();
4     private Elvis() { ... }
5
6     public void leaveTheBulding() { ... }
7 }

私有构造器仅被调用一次,用来实例化公有的静态final域Elvis.INSTANCE。

优点:缺少共有的或者受保护的构造器,所以保证了Elvis的全局唯一性:一旦Elvis类被实例化了,只会有一个Elvis实例。

缺点:享有特权的客户端可以借助AccessibleObject.setAccessible方法,通过反射机制调用私有构造器。

解决方案:修改构造器,让它在被要求创建第二个实例时抛出异常。

公有域方法的主要好处在于,组成类的成员的声明很清楚地表明了这个类是一个Singleton,公有的静态域是final的,所以该域将总是包含相同的对象引用。

在实现Singleton的第二种方法中,公有的成员是个静态工厂方法:

 1 public class Elvis {
 2     private static final Elvis INSTANCE = new Elvis();
 3     private Elvis() {};
 4     public static Elvis getInstance() {
 5         return INSTANCE;
 6     }
 7
 8     public void leaveTheBuilding() {};
 9 }

对于静态方法Elvis.getInstance的所有调用,都会返回同一个对象引用,所以,永远不会有创建其他的Elivs实例。

缺点:工厂方法返回该类的唯一实例,但是,它很容易被修改,比如改成为每个调用该方法的线程返回一个唯一实例。

工厂方法的优势之一在于,它提供了灵活性:在不改变其API的前提下,我们可以改变该类是否为Singleton的想法。第二个优势与泛型有关。

实现Singleton的第三种方法,只需要编写一个包含单个元素的枚举类型:

1 public enum Elvis {
2     INSTANCE;
3
4     public void leaveTheBuilding() {};
5 }

原文地址:https://www.cnblogs.com/remote/p/10066927.html

时间: 2024-11-02 21:34:22

用私有构造器或者枚举类型强化Singleton属性的相关文章

用私有构造器或者枚举类型强化singleton属性——Effective Java 读书笔记

/** * 实现singleton的第二种方法,共有成员是个静态工厂方法. * (第一种方法中公有静态成员是个final域,即直接使用private static final Singleton INSTANCE = new Singleton();) * @author 刘向峰 * */ public class Singleton { private static final Singleton INSTANCE = new Singleton(); /** * 享有特权的客户端可以借助 j

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

Singleton指仅仅被实例化一次的类.一般用来搞那些创建非常耗资源或者要求系统中只能有一个实例的类.这个非常常用.记得以前实习面试的时候就有这个面试题.一般采用的方法是将构造器私有化,然后提供一个static变量,再提供一个static的public方法用来返回static实例: //Singleton with static factory public class Elvis { private static final Elvis INSTANCE = new Elvis(); pri

第二章:创建和销毁对象。ITEM3:用私有构造器或者枚举类型强化Singleton属性。

声明一个Singleton类的3种方法: package com.twoslow.cha2; /** * 可以通过AccessibleObject.setAccessible(),通过反射机制调用私有构造器. * @author sai * */ public class Singleton01 { private Singleton01(){} public static final Singleton01 INSTANCE = new Singleton01() ; private Obje

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

??Singleton指仅仅被实例化一次的类 [Gamma95].Singleton通常代表无状态的对象,例如函数(第24项)或者本质上唯一的系统组件.使类称为Singleton会使它的客户端测试变得十分困难,因为除非它实现了作为其类型的接口,否则不可能将模拟实现替换为单例. ??实现单例的方法有两种. 两者都基于保持构造函数私有并导出公共静态成员以提供对唯一实例的访问. 在一种方法中,该成员是final字段: // Singleton with public final field publi

第三条 私有化构造器或者枚举类型强化Singleton属性

1.5版本之前,我们通常实现单例模式有两种方式: 两种方法前提都是私有化构造器,然后通过不同的方式获取对象. 第一种:通过公共的静态变量获取 public class Elivs{ // 私有化构造器 private Elivs(){} // 通过静态私有变量保存对象 public static final Elivs INSTANCE = new Elivs(); } 第二种:通过静态方法获取 public class Elivs{ // 私有化构造器 private Elivs(){} //

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

public class Elvis { //第一种静态成员是一个final域 public static final Elvis INSTANCE = new Elvis(); //第二种公有成员是一个静态工厂方法 private static final Elvis INSTANCE2 = new Elvis(); public static Elvis getInstance() { return INSTANCE2; } public static void main(String[]

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

参考Effective Java第三版 Joshua J. Bloch 参与编写JDK的大佬,上次看Collections的源码时看见了他的名字,然后翻了翻书,竟然就是他写的! 1.常见的一种: public class Singleton { private static final Singleton INSTANCE=new Singleton(); private Singleton(){ //如果没有判断,可以通过反射使用构造函数创建对象,然后就不是单例了 if (INSTANCE!=

Effective Java 第三版——3. 使用私有构造方法或枚类实现Singleton属性

Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将近8年的时间,但随着Java 6,7,8,甚至9的发布,Java语言发生了深刻的变化. 在这里第一时间翻译成中文版.供大家学习分享之用. 3. 使用私有构造方法或枚类实现Singleton属性 单例是一个仅实例化一次的类[Gamma95].单例对象通常表示无状态对象,如函数(条目 24)或一个本质上唯一的系统

effectiveJava(3)强化Singleton属性

使类成为singleton会使它的客户端测试变得十分困难,因为无法给Singleton替换模拟实现,除非它实现一个充当其类型的接口. 在java1.5之前,有两种方法实现Singleton.两种方法都是要把构造器保持为私有的,并导出公有的静态成员,以便允许客户端能够访问该类的唯一实例.在单线程的条件下运行. 方法一:公有域方法,优势:组成类的成员的声明很清楚地表明了这个类是一个Singleton.公有的静态域是final的,所以该域将总是包含相同的对象引用. //Singleton with p