【发布时间】:2013-08-04 19:15:03
【问题描述】:
在没有实现Serializable 的类中使用transient 关键字是否有意义?
因为没有实现Serializable 的类仍然可以被ObjectOutputStream 序列化。
【问题讨论】:
标签: java serializable transient
在没有实现Serializable 的类中使用transient 关键字是否有意义?
因为没有实现Serializable 的类仍然可以被ObjectOutputStream 序列化。
【问题讨论】:
标签: java serializable transient
出于多种原因,您可能仍希望将其标记为瞬态。立即想到的两个是:
它可以帮助传达该字段的语义目的。即,它可以帮助任何阅读您的代码的人理解该变量的含义
第三方库可以使用关键字。例如,Google 的 Gson 库可以将任何对象序列化/反序列化到 JSON,无论它是否实现 Serializable。在这种情况下,Gson 将(默认情况下)跳过标记为瞬态的字段。
【讨论】:
因为对象序列化比 Serializable 的简单实现更复杂(想想代理:代理对象可以实现 Serializable,但不是原始对象,并且在您的代码中您仍然使用原始类)
实现序列化的另一种方法是 Externalizable完全控制对象序列化的接口或(来自 javadoc):
在序列化过程中需要特殊处理的类和
反序列化过程必须实现具有这些确切签名的特殊方法:
private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException;
private void writeObject(java.io.ObjectOutputStream stream) throws IOException
private void readObjectNoData() throws ObjectStreamException;
查看ObjectOutputStream javadoc 了解有关序列化过程/机制的更多信息。
编辑:回答您的问题,transient 是一个仅在序列化上下文中使用的关键字,因此带有瞬态字段的 not Serializable 对象没有意义
【讨论】:
因为没有实现
Serializable的类仍然可以被ObjectOutputStream序列化。
这是不正确的。那会抛出一个NotSerializableException。
writeObject() 采用Object 而不是Serializable 的原因是签名来自实现接口ObjectOutput,该接口独立于序列化定义。但是,它会阻止 ObjectOutputStream 更改其签名。
public interface ObjectOutput {
// ...
void writeObject(Object obj);
}
【讨论】:
通常,如果超类实现Serializable,它的子类也是可序列化的。这是唯一可以使字段瞬态并且类不直接实现可序列化的情况,但除此之外,如果类不可序列化让它们瞬态是没有意义的。
【讨论】:
不,这没有意义。
class State {
// The 'transient' modifier has no effect here because
// the 'State' class does not implement 'Serializable'.
private transient int[] stateData;
}
【讨论】: