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 Object Serialization Specificationから:

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 に答える