最近在读《大话设计模式》的单例模式(Singleton Pattern),想到以前收藏的文章,多种实现单例模式的方式:饿汉式、懒汉式、静态内部类、枚举方法等。对枚举类实现单例不是很理解,所以在网上查了相关资料,大多都是这样写的:
class Resource{
}
public enum SomeThing {
INSTANCE;
private Resource instance;
SomeThing() {
instance = new Resource();
}
public Resource getInstance() {
return instance;
}
}
刚开始看到有点奇怪,按照代码含义,它想要把Resource类做成单例。但是Resource类明明可以自己new Resource()来进行创建啊。何必写个enum类进行getInstance()呢???真是越看越糊涂了。最后发现枚举类实现单例出自《Effective Java》,就特地下载了pdf版本,查看了原文:
public enum Elvis{
INSTANCE;
// method
}
其实原文的意思是:把想要写成单例的类写成Enum就行了,因为Enum也支持方法定义,可以满足正常需求。例如:
public enum MingFather {
INSTANCE;
public void speak(){
System.out.println("叫爸爸!");
}
}
简单测试:
public class Main {
public static void main(String[] args) throws Exception {
MingFather.INSTANCE.speak();
// 简单引用
MingFather mf0 = MingFather.INSTANCE;
MingFather mf1 = MingFather.INSTANCE;
System.out.println("mf0===" + mf0.hashCode());
System.out.println("mf1===" + mf1.hashCode());
// 反射测试
Class clazz = MingFather.class;
MingFather mf2 = (MingFather) Enum.valueOf(clazz, "INSTANCE");
MingFather mf3 = (MingFather) Enum.valueOf(clazz, "INSTANCE");
System.out.println("mf2===" + mf2.hashCode());
System.out.println("mf3===" + mf3.hashCode());
// 序列化测试
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("test")));
oos.writeObject(mf0);
oos.close();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("test")));
MingFather mf4 = (MingFather) ois.readObject();
ois.close();
ObjectInputStream ois1 = new ObjectInputStream(new FileInputStream(new File("test")));
MingFather mf5 = (MingFather) ois1.readObject();
ois1.close();
System.out.println("mf4===" + mf4.hashCode());
System.out.println("mf5===" + mf5.hashCode());
}
}
输出结果:
叫爸爸!
mf0===118352462
mf1===118352462
mf2===118352462
mf3===118352462
mf4===118352462
mf5===118352462
总结:做的不够深入,相对来说只是简单的测试。不过,我重点想表达的是Enum到底如何实现单例模式!