有没有办法在Java中反序列化对象的一部分?

时间:2011-12-13 20:13:43

标签: java serialization

假设场景:实现Message的{​​{1}}类型对象的输出流。 Serializable有成员MessageHeaderBody很小,Header可能很大。假设我想根据Body中的信息编写过滤器:有没有办法在不必反序列化Header的情况下执行此操作?

3 个答案:

答案 0 :(得分:3)

首先,您不应通过声明transient来序列化Body。

但是,如果您已经序列化了Message对象,则无法有选择地反序列化特定成员。

答案 1 :(得分:2)

您刚刚发现了与数据库相比面向对象编程的一个弱点:“如果我只想要一半Customer对象怎么办?”

我要说的是你需要将Message类拆分成类似MessageHeader的东西,带有头信息而没有对body的引用,以及一个MessageBody类,它有一个body和一个可以用来查找的键标题数据。然后,您需要单独存储和检索序列化的MessageHeader和MessageBody对象。

答案 2 :(得分:1)

您可以编写自定义readObject()以只读取所需的字段。 如果您只想阅读标题,则需要注意首先序列化标题,然后是正文。然后在自定义的readObject()方法中,您可以选择只读取第一个元素。

public class Message implements Serializable {

  private transient String header;
  private transient String body;

  ...
  // custom write object that writes header first and then body
  private void writeObject(java.io.ObjectOutputStream oos)
      throws IOException {
    oos.defaultWriteObject();
    // explicitly store the transient fields
    oos.writeObject(header);
    oos.writeObject(body);
  }

  private void readObject(java.io.ObjectInputStream ois) 
      throws IOException, ClassNotFoundException {
    ois.defaultReadObject();
    // explicitly read in the transient fields
    header = (String) ois.readObject();
    if (needBody()) { // use some static/thread local variable to set this condition
      body = (String) ois.readObject();
    }
  }
}