Java 经验法则3 用私有构造方法或枚举类型强化Sigleton属性
单例
Singleton指仅仅被实例化一次的类。也就传说中得单例。
一般实现Singleton方法如下:
饿汉模式1
public class Elvis{
public static final Elvis INSTANCE = new Elvis();
private Elvis(){
//...
}
public void sayHello(){...}
}
饿汉模式2(使用静态工厂方法访问,推荐)
public class Elvis{
private static final Elvis INSTANCE = new Elvis();
private Elvis(){
//...
}
public void sayHello(){...}
public static Elvis getInstance(){
return INSTANCE;
}
}
饿汉模式3
public class Elvis{
private Elvis INSTANCE = null;
static{
INSTANCE = new Elvis();
}
private Elvis(){
//...
}
public void sayHello(){...}
public static Elvis getInstance(){
return INSTANCE;
}
}
懒汉模式1(延迟加载,线程不安全)
public class Elvis{
private static Elvis INSTANCE = null;
private Elvis(){
//...
}
public void sayHello(){...}
public static Elvis getInstance(){
if(INSTANCE == null){
INSTANCE = new Elvis();
}
return INSTANCE;
}
}
懒汉模式2(延迟加载,线程安全,效率略低)
public class Elvis{
private static Elvis INSTANCE = null;
private Elvis(){
//...
}
public void sayHello(){...}
public static synchronized Elvis getInstance(){
if(INSTANCE == null){
INSTANCE = new Elvis();
}
return INSTANCE;
}
}
静态内部类(延迟加载,线程安全,推荐)
public class Elvis{
private static class SingletonHolder{
private static final Elvis INSTANCE = new Elvis();
}
private Elvis(){
//...
}
public void sayHello(){...}
public static final Elvis getInstance(){
return SingletonHolder.INSTANCE;
}
}
单元素枚举类型(线程安全,无偿序列化,防止反射攻击,极力推荐)
public enum Elvis{
INSTANCE;
private Elvis(){...}
public void sayHello(){...}
}
注:除了枚举方式实现,以上方法实现Singleton的类序列化需要以下操作
- implements Serializable
- 加入以下方法
private Object readResolve(){
return INSTANCE;
}
枚举Singleton优势
- 自由序列化;
- 保证只有一个实例(即使使用反射机制也无法多次实例化一个枚举量);
- 线程安全
枚举Singleton缺点
- 失去了一些类特性
- 不能延迟加载