[coolxing按: 转载请注明作者和出处, 如有谬误, 欢迎在评论中指正.]
singleton模式是大多数javaer耳熟能详的, 不过要做到真正的单例其实很不容易, 你需要考虑以下问题:
1. 延迟加载时多线程环境下是否能保证单例?
2. 是否可以通过暴力反射获得新的对象?
3. 是否可以通过clone方法获得新的对象?
4. 是否可以通过序列化获得新的对象?
对于问题1, 可以通过双重检查加锁解决. 这是运用单例的常识, 不再详细说明.
问题2, 3, 4则是很难避免的.
但是我们可以通过java提供的一种简单的方式创建一个真正的singleton类: 仅有一个实例的枚举类型. 如:
public enum Weekday {
MONDAY;
private Weekday() {}
}
下面我们对这个枚举类进行一一验证.
暴力反射
测试代码如下:
public static void main(String[] args) throws Exception {
Class<?> clazz = Weekday.class;
Constructor<?> cc = clazz.getDeclaredConstructor(null);
cc.setAccessible(true);
cc.newInstance(null);
}
运行结果是抛出异常:Exception in thread "main" java.lang.NoSuchMethodException: cn.xing.test.Weekday.<init>()
明明Weekday有一个无参的构造函数, 为何不能通过暴力反射访问?
最新的Java Language Specification (§8.9)规定: Reflective instantiation of enum types is prohibited. 这是java语言的内置规范.
clone方法
所有的枚举类都继承自java.lang.Enum类, 而不是Object类. 在java.lang.Enum类中clone方法如下:
protected final Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
调用该方法将抛出异常, 且final意味着子类不能重写clone方法, 所以通过clone方法获取新的对象是不可取的.
序列化
java.lang.Enum类的readObject方法如下:
private void readObject(ObjectInputStream in) throws IOException,
ClassNotFoundException {
throw new InvalidObjectException("can't deserialize enum");
}
private void readObjectNoData() throws ObjectStreamException {
throw new InvalidObjectException("can't deserialize enum");
}
同暴力反射一样, Java Language Specification (§8.9)有着这样的规定: the special treatment by the serialization mechanism ensures that duplicate instances are never created as a result of deserialization.
综上所述, 创建仅有一个实例的枚举类型是实现singleton的最简单, 最严谨的方式.
Java Language Specification下载路径:http://docs.oracle.com/javase/specs/
分享到:
相关推荐
用VC实现的singleton 模式 在VS03,VC6.0下编译通过
java singleton 不解释不解释不解释不解释
C++完美实现Singleton模式
单例模式,Singleton两种代码实现。一般实现方法,泛型实现方法(推荐)
实现了单例模型。 vs2015的工程
在ACE的实现中就大量使用ACE_Singleton模板类将普通类转换成具有Singleton行为的类。这种方式很好地消除了一些重复代码臭味,而且,优化后的性能较标准互斥版本提高15倍。最近在用C++/CLI做一些工作,Singleton不可...
Laravel开发-singleton-pattern 帮助程序包来实现单例类。
本文档,是利用C++来实现设计模式中的,单例模式,里面有内容说明和相关实例代码介绍
# Python实现《剑指offer》 部分代码自己添加了一些测试用例, 或者自己添加了一些功能 1. 初级程序员注重算法和数据结构 2. 事先做好准备,对工作有热情 3. 面试过程放松。不要急于写代码,了解清楚所要解决的问题,...
# Python实现《剑指offer》 部分代码自己添加了一些测试用例, 或者自己添加了一些功能 1. 初级程序员注重算法和数据结构 2. 事先做好准备,对工作有热情 3. 面试过程放松。不要急于写代码,了解清楚所要解决的问题,...
单例类只能有一个实例。 单例类必须自己创建自己的唯一实例。 单例类必须给所有其他对象提供这一实例。 Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接...
如果某个类管理了系统中的某种资源,那么我们只能创建该类的一个实例,此时用到singleton设计模式(后面为了简化将省略“设计模式”四个字)比较合适了。然而,如果不注意实现方法,很有可能会让我们碰到一些...
四种常见的单例: 1、没有构造函数(DEFINE_SINGLETON_DEFAULT); 2、有构造函数,构造函数没有参数(DEFINE_SINGLETON_CONSTRUCT_NO_PARAM); 3、有构造函数,构造函数有没有... 通过宏定义巧妙实现,使用也很方便!
单例模式(Singleton)的6种实现,单例模式(Singleton)的6种实现
简单的单例模式举例Singleton 分为恶汉式 懒汉式
单例模式 Singleton 单例模式线程安全问题和拓展
1、某些类创建比较频繁,对于一些大型的对象,这可以节省一笔很大的系统开销。 2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。 3、有些像交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个...