2

这个问题是关于 ObjectInputStream 以及它如何构建声明为瞬态的字段。考虑一个简单的 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上读到的内容

“反序列化过程会忽略声明为瞬态或静态的字段。对其他对象的引用会导致根据需要从流中读取这些对象。”

瞬态字段被忽略是什么意思?如果它们是瞬态的,如何从流中读取它们(即未序列化 - 我如何理解它......)

马蒂亚斯

4

2 回答 2

5

ois.readObject 之后 sc.y 的值是多少?

Someclass.y将是“默认值”。在这种情况下,因为它是一个对象,所以它将是null.

瞬态字段被忽略是什么意思?

它们没有被序列化——它们被跳过了。来自Java 对象序列化规范

Serializable 类必须执行以下操作:

  • 实现 java.io.Serializable 接口
  • 识别应该可序列化的字段(使用serialPersistentFields成员显式声明它们可序列化或使用transient关键字表示不可序列化字段。)

... 和 ...

最简单的技术是将包含敏感数据的字段标记为private transient. 瞬态字段不是持久性的,不会被任何持久性机制保存。标记该字段将防止状态出现在流中并在反序列化期间恢复。由于(私有字段)的写入和读取不能在类之外被取代,因此类的瞬态字段是安全的。

还有你的下一个问题:

如果它们是瞬态的,如何从流中读取它们

它们不在流中 - 所以,实际上,它们没有被读取。如上所述,最终作为该类型的“默认值”(null对于对象,0/false对于原语)。

“反序列化过程会忽略声明为瞬态或静态的字段。”

对于最常见的情况,序列化过程会忽略它们 - 因此,它们不在流中,也不会被反序列化。但是,如果您在序列化对象之后更改了类,以便曾经被序列化的字段现在被标记为瞬态,则反序列化过程将在流中找到该值时忽略该值。

于 2012-05-10T09:26:59.607 回答
1

ois.readObject 之后 sc.y 的值是多少?

其默认值:零、false 或 null。

瞬态字段被忽略是什么意思?

这意味着它们被忽略了。他们不参与序列化或反序列化过程。

如果它们是瞬态的(即未序列化),如何从流中读取它们

他们不是。它们不在要读取的流中。

于 2012-05-10T11:01:18.967 回答