文档章节

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

李白吃白菜
 李白吃白菜
发布于 2016/03/23 15:47
字数 766
阅读 109
收藏 0

Singleton通常被用来代表那些本质上唯一的系统组件,在JDK1.5之前,实现Singleton有两种方法。这两种方法都要把构造器保持为私有的,并导出公有的静态成员,以便允许客户端能够访问该类的唯一实现。

第一种方式:1.构造器私有,2,有一个公共的静态成员,并且是final的。

public class Singleton {
     
    private Singleton(){
        //在此将构造函数设置为private,防止该类在外部被实例化
    }

    public static final Singleton Instance = new Singleton();
     
    public void test(){
        System.out.println("Test...");
    }
 
}

构造方法私有化的作用:外面调用只能调用类的静态函数,而不能new去创建对象;私有构造函数只能在函数内部调用,外部不能实例化,所以私有构造函数可以防止该类在外部被实例化。不过享有特v权的客户端可以借助AccessibleObject.setAccessible()方法,通过反射机制调用私有构造器。如果需要抵御这种攻击,可以修改构造器,让他在被要求创建的第二个实例时候抛出异常。  

第二种方式:1,构造器私有,2,有一个私有的静态成员,但是有一个公共的静态工厂方法  

public class Singleton1 {
     
    private static final Singleton1 INSTANCE = new Singleton1();
     
    private Singleton1(){}
     
    public static Singleton1 getInstance(){
        return INSTANCE;
    }
     
    public void test(){
        System.out.println("Test...");
    }
     
 
}

这就是传说中的懒汉式的单例模式,一般情况下,为了防止多线程的时候创建多个实例,都会加上synchronized 关键字。

对于静态方法getInstance()方法的所有调用,都会返回同一个对象的应用。这种写法的好处是很清楚地表明了该类是一个Singleton,但是这种写法有另一个好处是,可以添加其他的静态工厂方法返回另一个新的实例,这样就可以将该类变为非Signleton。为了使利用上述方法实现Singleton类变成是可序列化的,仅仅在声明时加上“implements Serializable”是不够的。为了维护并保证Singleton,必须声明所有实例都是瞬时transient的,并提供 一个readResolve方法。否则每次反序列化一个序列化的实例时,都会创建一个新的实例。即会导致一个假冒的对象。为了防止这种情况,需要在单例类中增加readResolve方法。延伸如下:

public class Singleton implements Serializable {

 	public static final Singleton INSTANCE = new Singleton();

	private Singleton() {
	}
	private Object readResolve() {
	// Return the one true Elvis and let the garbage collector
	// take care of the Elvis impersonator.
	return INSTANCE;
	}

}

实现Singleton还有第三种方法,从JDK1.5开始,只需编写一个包含单个元素的枚举类型。推荐的写法:

public enum Singleton3 {
    INSTANCE;
     
    public void test(){
        System.out.println("test...");
    }
 
}

这种方法在功能上与公有域接近,但是它更简洁。虽然这种方法还没有广泛采用,但是单元素的枚举类型已经成为实现Singleton的最佳方法。

© 著作权归作者所有

李白吃白菜
粉丝 12
博文 33
码字总数 18863
作品 0
朝阳
私信 提问
Effective_Java_Index

基于《Effective Java 第三版》的读书笔记 创建和销毁对象 第1条:用静态工厂方法代替构造器 第2条:遇到多个构造参数时要考虑用构建器 第3条:用私有构造器或者枚举类型强化Singleton属性 ...

添仔哥哥
2017/08/26
39
0
第2章 创建和销毁对象

本章的主题是创建和销毁对象:何时以及如何创建对象,何时以及如何避免创建对象,如何确保它们能够适时地销毁,以及如何管理对象销毁之前必须进行的各种清理动作。   获取类的实例有两个方...

浣雨笑笑生
2016/03/02
64
0
用私有构造器或枚举类型强化Singleton属性(3)

1、Singleton 代表那些本质上唯一的系统组件、增加客户端调试难度 2、Singleton 实现方法1: 构造器保持私有 导出公有静态成员 享有特权的的客户端,采用AccessibleObject.setAccessible(),...

职业搬砖20年
2018/05/22
8
0
【01】Effective Java - 对象创建销毁

1、术语 (1)Java语言支持四种类型:接口、类、数组、基本类型(primitive),前三种为引用类型,而基本类型的值不是对象。 (2)方法的签名包括它的名称和所有参数的类型,签名不包括它的返...

xixicat
2014/07/03
103
0
《Effective Java》读书笔记

Effective Java读书笔记 第一章:引言 第二章:创建和销毁对象 第一条:创建对象的方式 1、构造器 2、 静态方法 3、构建器 第三条::强化singleton 1、三种方式实现单例 枚举实现(最佳方式)...

磊神Ray
2011/09/06
195
0

没有更多内容

加载失败,请刷新页面

加载更多

idea修改新的git地址

我们在项目变动中通常会遇到更换git地址情况,这里介绍一个在idea项目中简单更换git地址操作: 1、点击VCS; 2、点击Git; 3、点击Remotes; 具体步骤如图 4、点击框中链接即可在右边看到一个...

west_coast
19分钟前
6
0
将规则集传递给mixin

允许包装在mixin中定义的css块。 分离的规则集是一组CSS属性、嵌套规则集、媒体声明或者是存储在变量中的任何其他内容,我们可以将它包含在规则集中或其他结构中,并且所有属性都将复制到那里...

凌兮洛
21分钟前
4
0
玩转阿里云 Terraform(一):Terraform 是什么

从本文起,我将陆续推出一系列有关 Terraform 的文章,从概念,特点,工作机制,用法以及最佳实践等多个方面由浅入深的向大家介绍如何在阿里云上玩转 Terraform。同时也希望借此机会,与感兴...

阿里云官方博客
21分钟前
4
0
科研大数据面临的挑战

近几十年硬件的发展非常迅猛,第一台Macintosh苹果电脑的内存是128KB(0.13MB),现在很多笔记本配的是8GB的内存,硬盘1TB(1024GB),2TB的很常见。大型的数据服务器上还会有更大的储容量,...

英论阁学术院
21分钟前
5
0
python学习10.09:Python列表和元组的底层实现

有关列表(list)和元组(tuple)的底层实现,本节分别从它们的源码来进行分析。 首先来分析 list 列表,它的具体结构如下所示: typedef struct { PyObject_VAR_HEAD /* Vector o...

太空堡垒185
22分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部