在1.5版本之前可以两种实现Singleton的方法,但是都要把构造器保存为私有的。
1、公有静态成员是个final域
- // Singleton with public final field - Page 17
- public class Elvis {
- public static final Elvis INSTANCE = new Elvis();
- private Elvis() { }
- public void leaveTheBuilding() {
- System.out.println("Whoa baby, I'm outta here!");
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.INSTANCE;
- elvis.leaveTheBuilding();
- }
- }
问题:但是客户端可以通过AccessibleObject.setAccessible方法,通过反射机制调用私有构造器。
AccessibleObject 类是 Field、Method 和 Constructor 对象的基类。它提供了将反射的对象标记为在使用时取消默认 Java 语言访问控制检查的能力。对于公共成员、默认(打包)访问成员、受保护成员和私有成员,在分别使用 Field、Method 或 Constructor 对象来设置或获得字段、调用方法,或者创建和初始化类的新实例的时候,会执行访问检查。
在反射对象中设置 accessible 标志允许具有足够特权的复杂应用程序(比如 Java Object Serialization 或其他持久性机制)以某种通常禁止使用的方式来操作对象。
2、公有的成员是个静态工厂方法
这种方法很清晰的表明了这个类是一个Singleton
- // Singleton with static factory - Page 17
- public class Elvis {
- private static final Elvis INSTANCE = new Elvis();
- private Elvis() { }
- public static Elvis getInstance() { return INSTANCE; }
- public void leaveTheBuilding() {
- System.out.println("Whoa baby, I'm outta here!");
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.getInstance();
- elvis.leaveTheBuilding();
- }
- }
问题:同上
3、实现Singleton类变成可序列化的,仅仅实现序列化是不够的,为了维护并保证Singleton,必须声明所有实例域都是瞬时(transient)的,并提供一个readResolve方法。否则,每次反序列化一个序列的实例时,都会创建一个新的实例。
《The readResolve Method -- 序列化实现readResolve方法的作用》http://blog.csdn.net/partner4java/article/details/7058741
- import java.io.Serializable;
- // Serializable singleton with public final field - Page 18
- public class Elvis implements Serializable{
- public static final Elvis INSTANCE = new Elvis();
- private Elvis() { }
- public void leaveTheBuilding() {
- System.out.println("Whoa baby, I'm outta here!");
- }
- private Object readResolve() {
- // Return the one true Elvis and let the garbage collector
- // take care of the Elvis impersonator.
- return INSTANCE;
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.INSTANCE;
- elvis.leaveTheBuilding();
- }
- }
4、从JDK 1.5开始,实现Singleton,可以编写一个包含单个元素的枚举类型。
而且可以解决复杂的反序列化或者反射的攻击。
单元素的枚举类型已经成为实现Singleton的最佳方法。
- // Enum singleton - the preferred approach - page 18
- public enum Elvis {
- INSTANCE;
- public void leaveTheBuilding() {
- System.out.println("Whoa baby, I'm outta here!");
- }
- // This code would normally appear outside the class!
- public static void main(String[] args) {
- Elvis elvis = Elvis.INSTANCE;
- elvis.leaveTheBuilding();
- }
- }
相关推荐
Singleton拥有一个私有构造函数,确保用户无法通过new直接实例化它。除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance()方法负责检验并实例化自己,然后存储在静态成员变量中...
1、没有构造函数(DEFINE_SINGLETON_DEFAULT); 2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM); 3、有构造函数,构造函数有没有参数版本(DEFINE_SINGLETON_CONSTRUCT_WITH_DEFAULT)...
C++完美实现Singleton模式
简单的单例模式举例Singleton 分为恶汉式 懒汉式
构造器私有化。② 它必须自行创建这个实例。含有一个该类的静态变量来保存这个唯一的实例。③ 它必须能向整个系统提供这个实例。 单例模式有两种实现方式:饿汉式和懒汉式。 饿汉式是指在类初始化时直接创建实例...
单例模式 Singleton 单例模式线程安全问题和拓展
单例模式(Singleton)
用VC实现的singleton 模式 在VS03,VC6.0下编译通过
Singleton pattern单例模式应用
单例模式,Singleton两种代码实现。一般实现方法,泛型实现方法(推荐)
Laravel开发-singleton-pattern 帮助程序包来实现单例类。
Java常用设计模式(SingleTon、FactoryMethod、AbstractFactory)
singleton是最常见的设计模式,但是要设计好却是不容易,尤其是多线程的时候,需要考虑线程安全的问题.
Android Singleton单例模式运用详解
java singleton 不解释不解释不解释不解释
在Java应用中,单例对象能保证在一个...3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了,只有使用单例模式,才能保证核心交易服务器独立控制整个流程。 CSDN代码的详细解释。
singleton pattern 的定义 主要应用方法 优缺点 通过代码 具体分析解释
设计模式-Singleton与Factory
此示例展示了Qml 的单例模式(类似全局对象,只生成一次实例,可全局使用) surfsky.cnblogs.com