【问题标题】:serialization and desrialization variable deletion序列化和反序列化变量删除
【发布时间】:2012-03-13 11:21:01
【问题描述】:

假设我序列化下面的类(通过给字段x 赋值,比如5),在进行反序列化之前,我删除字段x 并放入一个新字段yintfloat),结果会怎样?

我相信反序列化已成功完成,y 字段的值将是默认值,这是正确的吗?

如果这是正确的,x 的值将在序列化时从持久对象到有状态对象的转换中去哪里?

public class Cat implements Serializable{    
  private static final long serialVersionUID = 4231235177539824282L;  
  int x;
}

反序列化之前:

public class Cat implements Serializable{    
  private static final long serialVersionUID = 4231235177539824282L;  
  float/int y;
}

【问题讨论】:

    标签: java serialization


    【解决方案1】:

    序列化规范详细介绍了字段反序列化的内部工作原理(您可以在此处找到:http://docs.oracle.com/javase/7/docs/platform/serialization/spec/input.html

    如果您浏览“readObject 方法”部分,它会指出:

    对象的任何未出现在流中的字段都设置为 它的默认值。出现在流中但不在 对象,被丢弃。这主要发生在更高版本的 类写了前面没有出现的附加字段 版本。

    所以本质上,字段“x”在流中会有一些值,但会被丢弃,并且字段“y”将被设置为 0(默认值),因为它不会出现在流中。

    【讨论】:

    • 老一代删除字段和新一代添加字段实际上是相同的。他们都将在新一代设置默认值,那么一个是兼容的,一个是不兼容的?
    【解决方案2】:

    Jain007,我认为在这种情况下您可能会遇到异常,因为您“删除”了一个字段。

    仅供参考,以下是可能导致异常的不兼容更改: - 删除字段 - 更改类层次结构 - 将非静态更改为静态 - 将非瞬态更改为瞬态 - 更改原始字段的类型

    虽然以下是不会影响反序列化过程的兼容更改: - 添加字段 - 将字段从静态更改为非静态 - 将字段从瞬态更改为非瞬态 - 向对象树添加类

    【讨论】:

    • 就像我在 jdk5 上检查的一样,定义了 serialVersionUID,但情况并非如此 - 没有例外,但我也不确定,因为我也不相信并且想知道究竟是什么发生
    【解决方案3】:

    序列化数据包含将在反序列化期间使用的变量名称和签名。 y 将是默认值,因为它没有在序列化数据中描述。 x 值将丢失,例如新的 Cat 类不包含具有合适签名的变量。
    http://docs.oracle.com/javase/6/docs/platform/serialization/spec/protocol.html

    【讨论】:

      猜你喜欢
      • 2012-10-31
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      相关资源
      最近更新 更多