【问题标题】:To initialize a transient field, what is the most simple solution要初始化瞬态字段,最简单的解决方案是什么
【发布时间】:2010-10-18 15:11:51
【问题描述】:
class MyClass implements Serializable {
  transient int myTransient;
  //Other variables
}

当我恢复这个类时,我想手动初始化myTransient,否则我只想使用默认的序列化。

如何在不重写整个序列化机制的情况下将init() 方法注入对象恢复过程,就像Externalizable 会让我这样做?

【问题讨论】:

  • 我想到了惰性初始化。这里有两个问题。如果您不使用锁定,您的变量可能会被初始化多次。如果你锁定,它可能会减慢你的应用程序。查看延迟初始化的双重检查锁定:cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html。 axtavt 的解决方案更好。

标签: java serialization


【解决方案1】:

实现readObject() 方法:

private void readObject(java.io.ObjectInputStream in)
    throws IOException, ClassNotFoundException {
    in.defaultReadObject();
    myTransient = ...;
}

来自 javadoc:

在序列化和反序列化过程中需要特殊处理的类必须实现具有这些确切签名的特殊方法:

private void readObject(java.io.ObjectInputStream in) 抛出 IOException,ClassNotFoundException;

readObject 方法负责从流中读取并恢复类字段。它可以调用 in.defaultReadObject 来调用用于恢复对象的非静态和非瞬态字段的默认机制。 defaultReadObject 方法使用流中的信息将保存在流中的对象的字段分配给当前对象中相应命名的字段。这可以处理类已演变为添加新字段的情况。该方法不需要关注属于其超类或子类的状态。通过使用 writeObject 方法或使用 DataOutput 支持的原始数据类型的方法将各个字段写入 ObjectOutputStream 来保存状态。

另请参阅:

【讨论】:

  • 如果您需要一些默认实现中未包含的功能,您可以定义自己的序列化,但 readObject 应该足以用于变量初始化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多