WEB开发网
开发学院软件开发Java 关于 Java 对象序列化您不知道的 5 件事 阅读

关于 Java 对象序列化您不知道的 5 件事

 2010-05-05 00:00:00 来源:WEB开发网   
核心提示: 清单 5. 你完整了我,我代替了你classPersonProxyimplementsjava.io.Serializable{publicPersonProxy(Personorig){data=orig.getFirstName()+","+orig.getLastNam

清单 5. 你完整了我,我代替了你

class PersonProxy 
  implements java.io.Serializable 
{ 
  public PersonProxy(Person orig) 
  { 
    data = orig.getFirstName() + "," + orig.getLastName() + "," + orig.getAge(); 
    if (orig.getSpouse() != null) 
    { 
      Person spouse = orig.getSpouse(); 
      data = data + "," + spouse.getFirstName() + "," + spouse.getLastName() + ","  
       + spouse.getAge(); 
    } 
  } 
 
  public String data; 
  private Object readResolve() 
    throws java.io.ObjectStreamException 
  { 
    String[] pieces = data.split(","); 
    Person result = new Person(pieces[0], pieces[1], Integer.parseInt(pieces[2])); 
    if (pieces.length > 3) 
    { 
      result.setSpouse(new Person(pieces[3], pieces[4], Integer.parseInt 
       (pieces[5]))); 
      result.getSpouse().setSpouse(result); 
    } 
    return result; 
  } 
} 
 
public class Person 
  implements java.io.Serializable 
{ 
  public Person(String fn, String ln, int a) 
  { 
    this.firstName = fn; this.lastName = ln; this.age = a; 
  } 
 
  public String getFirstName() { return firstName; } 
  public String getLastName() { return lastName; } 
  public int getAge() { return age; } 
  public Person getSpouse() { return spouse; } 
 
  private Object writeReplace() 
    throws java.io.ObjectStreamException 
  { 
    return new PersonProxy(this); 
  } 
   
  public void setFirstName(String value) { firstName = value; } 
  public void setLastName(String value) { lastName = value; } 
  public void setAge(int value) { age = value; } 
  public void setSpouse(Person value) { spouse = value; }  
 
  public String toString() 
  { 
    return "[Person: firstName=" + firstName + 
      " lastName=" + lastName + 
      " age=" + age + 
      " spouse=" + spouse.getFirstName() + 
      "]"; 
  }   
   
  private String firstName; 
  private String lastName; 
  private int age; 
  private Person spouse; 
}

注意,PersonProxy 必须跟踪 Person 的所有数据。这通常意味着代理需要是 Person 的一个内部类,以便能访问 private 字段。有时候,代理还需要追踪其他对象引用并手动序列化它们,例如 Person 的 spouse。

这种技巧是少数几种不需要读/写平衡的技巧之一。例如,一个类被重构成另一种类型后的版本可以提供一个 readResolve 方法,以便静默地将被序列化的对象转换成新类型。类似地,它可以采用 writeReplace 方法将旧类序列化成新版本。

5. 信任,但要验证

认为序列化流中的数据总是与最初写到流中的数据一致,这没有问题。但是,正如一位美国前总统所说的,“信任,但要验证”。

对于序列化的对象,这意味着验证字段,以确保在反序列化之后它们仍具有正确的值,“以防万一”。为此,可以实现 ObjectInputValidation 接口,并覆盖 validateObject() 方法。如果调用该方法时发现某处有错误,则抛出一个 InvalidObjectException。

结束语

Java 对象序列化比大多数 Java 开发人员想象的更灵活,这使我们有更多的机会解决棘手的情况。

幸运的是,像这样的编程妙招在 JVM 中随处可见。关键是要知道它们,在遇到难题的时候能用上它们。

5 件事 系列下期预告:Java Collections。在此之前,好好享受按自己的想法调整序列化吧!

本文示例源代码或素材下载

上一页  3 4 5 6 7 8 

Tags:关于 Java 对象

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接