在枚举反序列化期间未调用readResolve()

时间:2017-02-26 06:43:22

标签: java serialization enums singleton deserialization

在重新序列化enum对象期间不会调用 readResolve()。 我试图做的原因是比较两种实现Singleton的方法。

Singleton可以通过两种方式实现。

  1. 静态实例对象和私有构造函数的传统方式
  2. 使用单个对象枚举
  3. 第二种方式需要较少的编码。

    我正在比较这两种方法,以便超越单身人士的行为方式和程序员的照顾

    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? 怎么回事?

1 个答案:

答案 0 :(得分:1)

由于:

  1. readResolve() methods are ignored for Enums

  2. Enums已经没有打破单身模式。你不需要自己实现它。