37

私は Java の ArrayList のソースを読んでいて、そのバッキング配列宣言に出くわしました:

private transient Object[] elementData;

なぜこれは一時的である必要があるのですか? このクラスをシリアル化できないのはなぜですか?

助けてくれてありがとう!

4

6 に答える 6

39

シリアル化できます。クラスはArrayList、デフォルトのメカニズムを使用するのではなく、それ自体で処理を行います。標準のシリアル化メカニズムの一部である、そのクラスのメソッドwriteObject()とメソッドを見てください。readObject()

ソースを見るとwriteObject()、バッキングアレイが保存されていないことがわかります。代わりに、要素(null値を含む)を一度に1つずつsize()制限までシリアル化します。これにより、アレイ、特にアレイの最後にある未使用のスロットをシリアル化するオーバーヘッドが回避されます。デシリアライズ時に、必要最小限のサイズの新しいバッキング配列がによって作成されreadObject()ます。

于 2012-03-24T00:50:00.833 に答える
8

なぜこれは一時的である必要があるのですか?

これは、デフォルトよりも優れたシリアル化の仕事をするカスタムreadObjectとメソッドを提供するためです。writeObject具体的には、writeObjectメソッドは、要素のサイズとシーケンスのみを書き込みます。これにより、1)独自のヘッダーとオーバーヘッドがあり、2)通常はnullsが埋め込まれているプラ​​イベート配列オブジェクトのシリアル化が回避されます。スペースの節約は重要です。

このクラスをシリアル化できないのはなぜですか?

ArrayListクラス全体をシリアル化できます1。はObject[]直接シリアル化することもできますが、transient別の方法でシリアル化を実装するようにマークすることを選択しました。


1-実際、これは要素のランタイムタイプによって異なります。たとえば、ArrayList含まれているThread参照をシリアル化しようとすると、最初のnull以外の参照に対して実行時例外が発生します。

于 2012-03-24T00:47:29.680 に答える
5

ArrayListを実装Serializableしているので、シリアル化できます。これが、プライベートバッキング配列がである理由です。すべてが'sとメソッドtransientによって処理されるため、クラス内の他のデータと一緒にシリアル化されません。ArrayListwriteObjectreadObject

于 2012-03-24T00:47:52.970 に答える
2

明示的なシリアル化を実装しているためです。ArrayList#writeObjectを参照してください。

于 2012-03-24T00:47:33.800 に答える
0

変数はシリアル化できません。

  • 変数がシリアライズ可能でない場合、シリアライゼーション メカニズムは、変数をシリアライズしようとすると例外をスローします。これを回避するために、変数を一時的であると宣言できます。

変数は冗長です。

  • インスタンスが計算結果をキャッシュするとします。プロセッサ時間を節約するために、計算の結果をローカルに保存したい場合があります。しかし、ネットワーク経由でオブジェクトを送信すると、帯域幅の消費が心配になり、後でいつでも再生成できるため、キャッシュされた計算を破棄する可能性があります。

リンク: http://onjava.com/pub/a/onjava/excerpt/JavaRMI_10/index.html?page=3

于 2012-03-24T00:56:40.737 に答える