例一:提前初始化(感觉这种方法最简单)
public class Singleton {
private static Singleton singleton = new Singleton();
//让构造函数为 private,这样该类就不会被实例化
private Singleton() {
}
//方法修饰符为public static,获取唯一可用的对象
public static Singleton getInstance() {
return singleton;
}
}
例二:静态方法上加synchronized
public class Singleton {
private static Singleton singleton;
private Singleton() {
}
public synchronized static Singleton getInstance() {
if (singleton == null) {
singleton = new Singleton();
}
return singleton;
}
}
附:思考题,想想下面这行代码,输出结果是什么?(思考:类的初始化顺序和对象的初始化顺序)
package com.eastcom.self.monitor.alarm.processor.single;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class CachingEnumResolver {
private static final CachingEnumResolver SINGLE_ENUM_RESOLVER = new CachingEnumResolver();
private static Map<String, String> CODE_MAP_CACHE;
static {
CODE_MAP_CACHE = new HashMap<String, String>();
// 为了说明问题,我在这里初始化一条数据
CODE_MAP_CACHE.put("0", "北京市");
}
// private, for single instance
private CachingEnumResolver() {
// 初始化加载数据 引起问题,该方法也要负点责任
initEnums();
}
/**
* 初始化所有的枚举类型
*/
public static void initEnums() {
// ~~~~~~~~~问题从这里开始暴露 ~~~~~~~~~~~//
if (null == CODE_MAP_CACHE) {
System.out.println("CODE_MAP_CACHE为空,问题在这里开始暴露.");
CODE_MAP_CACHE = new HashMap<String, String>();
}
CODE_MAP_CACHE.put("1", "北京市");
CODE_MAP_CACHE.put("2", "云南省");
// ..... other code...
}
public Map<String, String> getCache() {
return Collections.unmodifiableMap(CODE_MAP_CACHE);
}
/**
* 获取单态实例
*
* @return
*/
public static CachingEnumResolver getInstance() {
return SINGLE_ENUM_RESOLVER;
}
public static void main(String[] args) {
System.out.println(CachingEnumResolver.getInstance().getCache());
}
}
参考文章及答案:https://www.ibm.com/developerworks/cn/java/j-lo-clobj-init/index.html