Singleton可以通过两种方式实现。
第二种方式需要较少的编码。
我正在比较这两种方法,以便超越单身人士的行为方式和程序员的照顾
1)克隆
以传统方式,不要在clone()方法中实现clonable接口或抛出错误。 在Enum方式中,不需要克隆,因为枚举无法实现克隆方法
2)通过反射创建对象
传统方式如果实例已经初始化,则在构造函数中抛出错误。 在Enum中,它不是必需的,因为我们不能反射地创建枚举对象。它会引发错误" java.lang.IllegalArgumentException:无法反射创建枚举对象"
3)序列化 - 反序列化
在传统的实现serializable接口或者实现readResolve()方法返回相同的实例。
现在在Enum中默认是可序列化的。所以我实现了readResolve(),但是在反序列化完成时没有调用readResolve()。 它自动给了我最新的Enum对象状态。 为什么会这样?
public enum MySingletonEnum {
instance(41,"Devendra");
private MySingletonEnum(int age, String name){
this.age = age;
this.name = name;
}
private int age;
private String name;
// getters and setters
public static MySingletonEnum getInstance(){
return instance;
}
//Hook for not breaking the singleton pattern while deserializing.
private Object readResolve() throws ObjectStreamException {
System.out.println("The constructed obejct has age="+age+" name="+name);
System.out.println("But now returning same instance");
return instance;
}
}
现在在调用类 我序列化了MySingletonEnum.getInstance()。所以我写的是age = 41和name = Devendra。
然后更改MySingletonEnum.getInstance()的属性,即" Age"至999和"姓名"到了" Kaushik"。
然后反序列化对象。
未调用readResolve()方法。仍然反序列化的对象的年龄= 999,Name = Kaushik。
public static void trySerialization() throws FileNotFoundException, IOException, ClassNotFoundException{
String filePath = "d:\\kaushik\\kaushik26Feb.txt";
File f = new File(filePath);
f.createNewFile();
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(filePath));
oos.writeObject(MySingletonEnum.getInstance());
oos.close();
MySingletonEnum.getInstance().setAge(999);
MySingletonEnum.getInstance().setName("Kaushik");
System.out.println("Printing values before deserialize");
MySingletonEnum.getInstance().print();
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(filePath));
MySingletonEnum deserializedObj = (MySingletonEnum)ois.readObject();
System.out.println("deserializedObj="+deserializedObj);
System.out.println(deserializedObj.getAge()+" ...."+deserializedObj.getName());
if(deserializedObj==MySingletonEnum.getInstance()){
System.out.println("Same instance");
}else{
System.out.println("Different instance");
}
}
输出
Printing values before deserialize
999 ....Kaushik
deserializedObj=instance
999 ....Kaushik
Same instance
如果没有显示41,Devendra? 怎么回事?