【问题标题】:Can I change member variable type of serializable class?我可以更改可序列化类的成员变量类型吗?
【发布时间】:2015-09-09 07:56:24
【问题描述】:

假设一个类实现了可序列化并且我序列化了该类的一个对象。在 ding 之后,我更改了内部实现,以便将变量的数据类型从 int 更改为 String.. 是否可以在使用 readresolve 反序列化时从序列化对象中获取值?

Class A implements Serializable{
  private int first;
  private int second;

}

序列化后:

Class A implements Serializable{

 private int first;
 private String second;

}

【问题讨论】:

  • 你为什么不试试呢?将类保存到文件,更改它,尝试读取它(提示:更改现有成员的类型是不兼容的更改)。

标签: java serialization


【解决方案1】:

您需要实现一个自定义的 readObject() 方法。更多信息here

在类的两个版本中,serialVersionUID 也需要相同。如果您尚未声明 serialVersionUID,则 jvm 将根据类的形状计算它。为此,您需要在新版本的类中显式声明旧的 serialVersionUID。更多信息here

【讨论】:

  • 如果我要添加一个新字段...用于更改数据成员的数据类型...我应该怎么做?
  • 您还需要定义serialPersistentFields 来指定旧类型。您可以使用不同的名称向其中添加额外的序列化字段。 (您还需要一个writeObject 方法。)
【解决方案2】:

无聊。让我们试试这个(未编译)...

import java.io.*;

class A implements Serializable {
    private static final long serialVersionUID = 0x...L;
    private static final ObjectStreamField[] serialPersistentFields = {
        new ObjectStreamField("first", int.class),
        new ObjectStreamField("second", int.class),
        new ObjectStreamField("secondString", String.class),
    };
    private int first;
    private String second;

    private void writeObject(ObjectOutputStream out) throws IOException {
         ObjectOutputStream.PutField fields = out.putFields();
         fields.put("first", first);
         int secondInt;
         try {
             secondInt = Integer.parseInt(second);
         } catch (NumberFormatException exc) {
             secondInt = -1;
         }
         fields.put("second", secondInt);
         fields.put("secondString", second);
     }
     private void readObject(
         ObjectInputStream in
     ) throws IOException, ClassNotFoundException {
         ObjectInputStream.GetField fields = out.readFields();
         fields = fields.get("first", 0);
         int secondInt = fields.get("second", 0);
         second = (String)field.get("secondString", Integer.toString(secondInt));
     }
}

如果其中任何一个字段是final,那么您需要readResolve 怪异或更糟。

(差点把最后一个secondInt 当作second 留在那里。嘘嘘到String.valueOf。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多