【问题标题】:Extract java superclass from serializable object with backwards compatibility从具有向后兼容性的可序列化对象中提取 java 超类
【发布时间】:2018-09-01 03:19:39
【问题描述】:

我想将类功能移至父类,但这会阻碍反序列化。起点是这样的:

package xso.test.serializable;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class WriteClass
{
  public static void main( String[] args ) throws Exception
  {
    MyClass d = new MyClass();
    d.i = 888;

    try (ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream( "MyClass.ser" ) ))
    {
      System.out.println( "Serializing" );
      oos.writeObject( d );
    }
  }
}

class MyClass implements Serializable
{
  /**
   * same serialVersionID as in ReadClassNew
   */
  private static final long serialVersionUID = -4436695035358861227L;

  int i = 10;
}

我想像这样将 MyClass 提取到一个新的 SuperClass (MyNewParentClass):

package xso.test.serializable;

import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.io.Serializable;

public class ReadClassNew
{
  public static void main( String[] args ) throws Exception
  {
    ObjectInputStream ois = new ObjectInputStream( new FileInputStream( "MyClass.ser" ) );
    System.out.println( "Deserializing" );
    MyClass clazz = (MyClass)ois.readObject();
    System.out.println( clazz.i );
  }
}

class MyNewParentClass implements Serializable
{
  /**
   * 
   */
  private static final long serialVersionUID = -6437613570659781444L;

  int i = 10;
}

class MyClass extends MyNewParentClass
{
  /**
   * same serialVersionID as in WriteClass
   */
  private static final long serialVersionUID = -4436695035358861227L;

  //int i = 10; // moved to parent class. (Field will not serialized any more sadly )
}

查看并重现问题:

  1. 运行第一个代码 sn -p。
  2. 运行第二个代码sn-p。 控制台输出将是:

      Deserializing
      0
    

如果您取消注释子类(MyClass)中的int i = 10;,您可以看到反序列化可以工作。但我想反序列化超类中的字段int i。

这可能吗? 感谢您的任何建议。

【问题讨论】:

  • 没有。这是一个不兼容的更改。见here。
  • @EJP URL 的锚点部分似乎不存在。你是说docs.oracle.com/javase/8/docs/platform/serialization/spec/… 吗?
  • 根据我的经验,Java 序列化非常脆弱。它通常很快实现,但我发现由于这样的原因无法维护。我强烈推荐 Externalizable 或其他一些持久化对象的机制。

标签: java serializable


【解决方案1】:

我想在EJP 的评论中添加一些内容。

当一个对象被序列化时,它的整个对象图都会被序列化。这意味着被序列化对象的实例变量引用的任何对象都被序列化,并且这些对象引用的任何对象......等等。在您的情况下,第一个代码片段中的class MyClass 对class MyNewParentClass 及其变量一无所知,所以基本上这两个指向堆上不同的内存字节。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    • 2012-04-17
    • 2017-04-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多