序列化和反序列化瞬态对象的棘手情况

时间:2012-10-14 12:07:36

标签: java serialization transient

这是我的代码:

class Collar {
  int size;
}

class Dog implements Serializable {
  int weight;
  transient Collar c;

  public Dog(int weight, int size) {
    this.weight = weight;
    c = new Collar();
    c.size = size;
  }

  public void writeObject(ObjectOutputStream os) throws Exception {
    os.defaultWriteObject();
    os.writeInt(c.size);
  }

  public void readObject(ObjectInputStream is) throws Exception {
    is.defaultReadObject();
    c = new Collar();
    c.size = is.readInt();
  }
}

public class test {
  public static final String FILE_REVISION = "$Revision$";

  public static void main(String ar[]) throws Exception {
    Dog dOut = new Dog(20, 2);

    System.out.println("DOut Weight: " + dOut.weight + " Size: " + dOut.c.size);

    FileOutputStream fo = new FileOutputStream("Dog.ser");
    ObjectOutputStream os = new ObjectOutputStream(fo);
    os.writeObject(dOut);

    FileInputStream fi = new FileInputStream("Dog.ser");
    ObjectInputStream is = new ObjectInputStream(fi);
    Dog dIn = (Dog) is.readObject();

    System.out.println("DIn Weight: " + dIn.weight + " Size: " + dIn.c.size);
  }
}

这是输出:

DOut Weight: 20 Size: 2
Exception in thread "main" java.lang.NullPointerException
    at test.main(test.java:55)

第55行是具有System.out.println()

的最后一行代码

该程序能够取回可序列化对象,这是Dog。但是,当我使用自定义readObject方法回读时,它无法创建一个新的“包含”对象Collar。我哪里错了?

正如您所看到的,'dIn.c.size'语句中的输出是NullPointerException。即使我在自定义readObject方法中将c设置为新对象,但它实际上并不起作用。

2 个答案:

答案 0 :(得分:2)

由于Collar c transient位于readObject内,您需要初始化c首先

c.size = is.readInt();<-- NullPointerException Here

您需要先在C初始化。

c = new Collar();
c.size = is.readInt();

这两种方法签名都不对,它们应如下所示:

 private void writeObject(ObjectOutputStream stream) throws IOException {
    stream.defaultWriteObject();
    stream.writeInt(c.size);
}

private void readObject(ObjectInputStream stream) throws IOException,
        ClassNotFoundException {
    stream.defaultReadObject();
    c = new Collar();
    c.size = stream.readInt();
}

您可以阅读有关序列化here

的更多详细信息

答案 1 :(得分:0)

Collar方法

中初始化您的readObject成员
public void readObject(ObjectInputStream is) throws Exception {
    is.defaultReadObject();
    c = new Collar();
    c.size = is.readInt();
}

修改  Serializable方法需要更改为私有。