通过ObjectInputStream和瞬态字段进行序列化

时间:2012-05-10 09:25:39

标签: java serialization transient objectinputstream

这个问题是关于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

2 个答案:

答案 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。

  

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

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

  

如果它们是瞬态的(即不是序列化的

),如何从流中读取它们

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