2011-02-07 9 views
28

なぜjava.util.ListSerializableを実装していませんが、サブクラスはLinkedList,Arraylistなどですが、相続の原則に反するように見えませんか?例えば、我々は、ネットワーク上でのLinkedListを送信したい場合は、私たちが書く必要があります:java.util.ListがSerializableを実装していないのはなぜですか?

new ObjectOutputStream(some inputStream).writeObject(some LinkedList); 

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

+2

私はあなたの声明の第2部分が正確ではないと思います。私はそれを試してみる機会がなかったと思います。どのようなエラーが表示されますか? –

答えて

35

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

LinkedListおよびArrayListこれを行うことを選択しますが、これはその実装に固有です。他のListの実装はSerializableではないかもしれません。

+2

その場合、同じ引数をLinkedListにも適用することができます。また、非常に基本的なリストであるため、リストの要件ではないため、直列化できません。 –

+10

リストのすべての実装をシリアライズ可能にし、その特定の実装をシリアライズ可能にすることに違いがあります。 –

+1

LinkedListは、開発者が直列化可能なプロパティを指定する実装です。あなたの推論に従えば、クラスは一度に2つのインターフェースを実装する必要はありません... – Dunaril

3

Listは、ユーザー固有のサブクラスによっても実装されているため、実装者は必ずSerializableを実装する必要はありません。シリアライズ可能性は、Listの主要な責任には属しません。したがって、2つをリンクさせる理由はありません。

7

Listは、インターフェイスであり、Serializableを拡張すると、Listの実装はすべてシリアル化可能でなければなりません。

serializableプロパティはList抽象化の一部ではないため、実装には必要ありません。

1

特定の時点におけるアクティブなスレッドのリストを含む仮想的なThreadList implements List<Thread>を検討してください。インプリメンテーションは、アクティブなスレッドを透過的にブラウズし、それらに簡単にアクセスできるようにします。そのような実装は直列化可能でなければなりません(Threadはシリアル化できません)。

彼女の実装が安全にシリアル化できるかどうかは、インターフェイスを実装する人が決定します。 Listは、タイプTのアイテムの順序付けられたコレクションを基本的に述べているのであまりにも一般的です。

3

いいえ。リンク付きリストは常にリストです。リンクされたリストをデシリアライズするとLinkedListのがリストであるため、あなたはlはLinkedListのが重要でない事実であることを

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

事実を書き込むことができます。あなたはリストを望んでいて、あなたはリストを持っています。

+0

本当ですか?シリアル化されていないインターフェイスにキャストした場合、オブジェクトを逆シリアル化する方法をランタイムがどのように理解していますか? – Dunaril

+1

キャストはデシリアライゼーション後に発生するため、ここでは重要ではありません - >キャストは大丈夫です – Puce

+3

ランタイムは、シリアライズされたバイトストリームに直列化されたオブジェクトのクラスの名前が含まれているためオブジェクトをシリアル化する方法を知っています。 ObjectInputStreamは、このクラスのインスタンスを作成し、それを直列化されたオブジェクトにあるデータで生成し、それを呼び出し側に返します。呼び出し元は、それが直列化されたリストであることを知り、返されたオブジェクトをListにキャストします。 –

-2
一覧/はSerializableを拡張実装している場合、あなたはリストのすべての実装クラス/サブクラスもSerializableのある契約を暗示している

リストコレクションを拡張し、それはインターフェースなので、それは何かを実装することはできません...

+3

おそらくOPは、 'List'が' Serializable' *を 'Collection'に拡張しなければならないことを意味していました。 – davin

0

必ずしも真実ではない。例えば、ForwardingListMultimapのguava-collectionsの実装を見てください。これは機能的にシリアライズ可能である必要はなく、リストはシリアライズ可能ではないため可能です。

0

世界ではなく、すべてのList実装がSerializableでなければならないので、なぜそれは... java.util.ListにはSerializableを実装していないことを

です。代わりに

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

我々が明示的に言っている反対側のオブジェクトを読みながら... あなたはそれを試してみましたか?そうすれば、それが機能することがわかるはずです。

1

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

しかし、これらのパラメータ場合と戻り値の型がSerializableた、あなたは、特定の実装の種類を知る必要がありません:それは今作品として

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

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

も同様に動作します(シリアライズ可能なキャストなしで)。

ObjectInputStreamとObjectOutputStreamは、呼び出すときにあなたの型について全く気にしません。彼らは手元のオブジェクトとそのクラスを見るだけです。

関連する問題