web-dev-qa-db-ja.com

Java.util.ListがSerializableを実装しないのはなぜですか?

_Java.util.List_がSerializableを実装していないのに、LinkedListArraylistなどのサブクラスが実装しているのはなぜですか?相続の原則に反しているようではありませんか?たとえば、Linkedlistをネットワーク経由で送信する場合は、次のように記述する必要があります。

_new ObjectOutputStream(some inputStream).writeObject(some LinkedList);
_

これまでのところ良好ですが、反対側のオブジェクトを読み取るときは、LinkedList l = (LinkedList)objectInputStream.readObject();ではなく、明示的にList l = (List)objectInputStream.readObject();と言う必要があります。書き込み機能をLinkedListからArrayListに変更する場合は、読み取り部分も変更する必要があります。 Listを実装するSerializableがあれば問題は解決します。

36
Swaranga Sarma

Listはリストの重要な要件ではないため、Serializableを実装していません。 Listのすべての可能な実装をシリアル化できるという保証(または必要性)はありません。

LinkedListおよびArrayListはそうすることを選択しますが、それはそれらの実装に固有です。他のList実装はSerializableではない場合があります。

44
Aaron

Listはインターフェースであり、Serializableを拡張することは、Listの実装がすべて直列化可能であることを意味します。

直列化可能プロパティはリスト抽象化の一部ではないため、実装には必要ありません。

9
Dunaril

Listはユーザー固有のサブクラスでも実装できるため、実装者はSerializableを実装する必要がない場合があります。シリアライザビリティはListの主要な責任にも属していないため、2つをリンクする理由はありません。

3
Péter Török

いいえ。LinkedListは常にリストです。リンクリストを逆シリアル化すると、LinkedListはリストであるため、次のように記述できます。

List l = (List) objectInputStream.readObject();

Lが実際にLinkedListであることは重要ではありません。あなたはリストが欲しかった、そしてあなたはリストを得た。

3
JB Nizet

あなたの質問は誤解に基づいているようです。オブジェクトをシリアル化するには、オブジェクト(またはそのクラス)がSerializableを実装する必要がありますが、タイプSerializable(またはいくつかのサブタイプ)の式を使用する必要はありません。 writeObjectメソッドがObjectではなくSerializableのパラメーター型を持ち、戻り型がreadObject()であることは非常に意図的です。

ただし、これらのパラメーターと戻り値の型がSerializableであっても、特定の実装型を知る必要はありません。

ObjectOutputStream stream = ...;
List myList = ...;
stream.writeObject((Serializable)myList);

そして

ObjectInputStream stream = ...;
List myList = (List) stream.readObject();

現在と同様に機能します(Serializableキャストなし)。

ObjectInputStreamとObjectOutputStreamは、呼び出すときにタイプをまったく気にしません。単に手元のオブジェクトとそのクラスを見るだけです。

2
Paŭlo Ebermann

架空のThreadList implements List<Thread>、任意の時点でアクティブなスレッドのリストを含みます。実装はアクティブなスレッドを透過的に参照し、それらに簡単にアクセスできるようにします。そのような実装はシリアライズ可能である必要がありますか(Threadはシリアライズ可能ではないことを忘れて)?

実装をシリアライズしても安全かどうかを決定するのは、インターフェースを実装する人次第です。 Listは、基本的に* Tタイプのアイテムの順序付けられたコレクションを示すため、あまりにも一般的です。

2

ListがSerializableを実装/拡張する場合、Listのすべての実装クラス/サブクラスもSerializableであり、常に真であるとは限らないという契約を暗示しています。たとえば、 ForwardingListMultimap のguava-collections実装を見てください。機能的にシリアル化可能である必要はありません。これは、Listがシリアル化可能でないためにのみ可能でした。

0

Java.util.ListがSerializableを実装していないのはなぜですか...

世界中のすべてのList実装がSerializableである必要はないためです。

反対側のオブジェクトを読んでいる間、私たちは明示的に言う必要があります...の代わりに

List l = (List) objectInputStream.readObject();

試しましたか?もしそうなら、私はそれがうまくいくと思うでしょう。

0
Bert F