这个问题是关于ObjectInputStream以及它如何构建声明为transient的字段。考虑一个简单的ObjectInputStream用例
FileInputStream fis = new FileInputStream("t.tmp");
ObjectInputStream ois = new ObjectInputStream(fis);
SomeClass sc = (SomeClass) ois.readObject();
SomeClass在哪里
class SomeClass {
int x;
transient OtherClass y;
}
class OtherClass {
int z;
}
在ois.readObject之后sc.y的值是什么?
我要求澄清我在docs.oracle.com所说的内容
“反序列化过程会忽略声明为transient或static的字段。对其他对象的引用会导致必要时从流中读取这些对象。”
忽略瞬态字段是什么意思?如果它们是瞬态的(即没有序列化 - 我是如何理解的......),如何从流中读取它们。
的Matthias
答案 0 :(得分:4)
在ois.readObject之后sc.y的值是什么?
Someclass.y
将成为“默认值”。在这种情况下,因为它是一个对象,它将是null
。
忽略瞬态字段是什么意思?
他们没有被序列化 - 他们被忽略了。来自Java Object Serialisation Specification:
Serializable类必须执行以下操作:
- 实现java.io.Serializable接口
- 确定应该可序列化的字段 (使用
serialPersistentFields
成员明确声明可序列化或使用transient
关键字表示不可序列化字段。)
......和......
最简单的方法是将包含敏感数据的字段标记为
private transient
。 瞬态字段不是持久性的,并且不会被任何持久性机制保存。标记该字段将阻止状态显示在流中,并防止在反序列化期间恢复。由于(私有字段)的写入和读取不能在类之外被取代,因此该类的瞬态字段是安全的。
你的下一个问题是:
如果它们是瞬态的,那么如何从流中读取它们
他们不在流中 - 所以,实际上,他们不会被阅读。如上所述,最终为该类型的“默认值”(对象为null
,基元为0
/ false
。
“反序列化过程会忽略声明为瞬态或静态的字段。”
对于最常见的情况,它们被序列化进程忽略 - 因此,它们不在流中,并且不会被反序列化。但是,如果在序列化对象之后更改了类,以便以前将序列化的字段标记为瞬态,则反序列化过程将在流中找到它时忽略该值。
答案 1 :(得分:0)
在ois.readObject之后sc.y的值是什么?
其默认值:零,false或null。
忽略瞬态字段是什么意思?
这意味着他们被忽略了。他们不参与序列化或反序列化过程。
如果它们是瞬态的(即不是序列化的
),如何从流中读取它们
他们不是。它们不在要读取的流中。