Java 在枚举反序列化期间未调用readResolve()
在对枚举对象进行反序列化期间,不会调用readResolve()。 我试图做的原因是比较实现单身的两种方式 Singleton可以通过两种方式实现Java 在枚举反序列化期间未调用readResolve(),java,serialization,enums,singleton,deserialization,Java,Serialization,Enums,Singleton,Deserialization,在对枚举对象进行反序列化期间,不会调用readResolve()。 我试图做的原因是比较实现单身的两种方式 Singleton可以通过两种方式实现 静态实例对象和私有构造函数的传统方法 使用单对象枚举 第二种方法需要更少的编码 我比较了这两种方法,比较了重写单例行为的方法和程序员应该注意的事项 1) 克隆 在传统方法中,不实现可克隆接口或在clone()方法中抛出错误。 在枚举方式中,不需要它,因为克隆是不可能的,因为枚举无法实现可克隆方法 2) 通过反射创建对象 在传统方法中,若实例已经初始化
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()。所以我写的是年龄=41,名字=Devendra
然后将MySingletonEnum.getInstance()的属性,即“Age”更改为999,“Name”更改为“Kaushik”
然后反序列化对象
未调用readResolve()方法。仍然反序列化的对象的年龄为999,名称为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,德文德拉?
怎么会这样?因为:
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;
}
}
enum
已经没有打破单例模式。您不需要自己实现这一点enum
已经没有打破单例模式。您不需要自己实现这一点您是如何更改MySingletonEnum.getInstance()的属性的?这样做的?因为聪明的Java工程师已经确保枚举不会被序列化破坏,并且对于给定的类加载器,每个枚举实例只存在一次。查看您是如何操作的
,然后更改MySingletonEnum.getInstance()的属性。
这?使用年龄和名称的setter方法,因为聪明的Java工程师已经确保枚举不会被序列化破坏,并且对于给定的类加载器,每个枚举实例只存在一次。看见