2013-07-23 13 views
11

Javaでは、いくつかの理由でCollection-interfacesがSerializableを拡張しません。さらに、これらのインターフェイスの最も一般的な実装では、Serializableが実装されています。Java:直列化可能なコレクションを保証する方法

Collectionオブジェクトのいずれかを実装するオブジェクトは、コレクション自体のオブジェクトがすべてシリアライズ可能な場合は、実装自体がシリアル化可能(通常の場合)およびの場合はシリアル化可能です。

しかし、これらの2つの条件が満たされるようにするにはどうすればよいですか?コンパイラがこれらの条件をチェックできるので、私は実行時エラーに遭遇したくありません。私は(リスト-インタフェースのためのショーケース)のようないくつかの明白なインタフェースを考えている:

public interface SerializableList<T extends Serializable> extends Serializable, List<T> {} 

誰もこの問題に直面していないし、この簡単な解決策を思い付いている場合、私は思ったんだけど。今まで私は何か解決策や議論を見つけることができず、私の考えに疑問を呈していました。

+0

あなたの質問が正しく理解できれば、 'List'リファレンスを' List 'とすることができます。独自のインターフェイスを展開する必要はありません。 –

+0

コンパイラはそれを確認できません。 Serializableを実装しているすべてのクラスには、非一時的で非シリアル化可能なフィールドが含まれている可能性があり、実行時例外が発生します。 ArrayList は、それに含まれる実際のオブジェクトがシリアライズ可能な場合は、シリアライズ可能です。それが本当に重要であれば、単体テストを使用してください。 –

+1

@RohitJain:あなたの提案は、リスト内のオブジェクトが直列化可能であることを保証しますが、List実装自体は保証しません。 – MrD

答えて

6

は何が本質的を求めるには、2つの種類に参加型定義でありますよくCollection<? extends Serializable>です。このような型定義は、Java言語ではサポートされていません。

:あなたはこのような何かをしようとするまで

interface SerializableCollection<T extends Serializable> extends Collection<T>, Serializable {}

は、OKようだ:あなたはすでに書いたように

、最も明白な解決策は、これらの二つの他のインターフェイスに参加、独自のインタフェースを宣言することであってもよいですSerializableCollection<String> a = new ArrayList<String>();

これはコンパイルされません。 ArrayList<String>Collection<? extends Serializable>Serializableの両方を実装しても、クラスにはSerializableCollection<String>が実装されていません。あなたが希望の場合

さて、あなたは、新しいクラスを宣言することでも、この問題を回避することができます

SerializableArrayList<T extends Serializable> extends ArrayList<T> implements SerializableCollection<T> {}

今、あなたは、本質的に、あなたが必要なすべてを組み合わせていますし、元の要件を満たすことができるようになります。

SerializableCollection<String> a = new SerializableArrayList<String>();

努力する価値はありますか?あなたの場合、決定する必要がありますが、私はいいえと言います。私の議論は、Serializableマーカーがちょうど非形式的な「ラベル」なので、あなたのコレクションとそのコンテンツが両方ともSerializableを実装していることが保証されているとは限りません。

+1

ありがとうございます。私はすべてが今私にとって明らかだと思う。あなたとJB Nizetが述べているように、 'Serializable'インターフェースを実装しているオブジェクトが本当にシリアライズ可能であることに頼ることはできません(残念です)。 私はこれがポイントだと思います:努力する価値はありますか?それが私の場合に当てはまるなら、私はそれについて考えるでしょう。 – MrD

6

Serializableはすばらしいインターフェイスではありません。それらが実装されたときに利用可能だった場合は、注釈であったはずです。

ListのどれかがSerializableではないと、どのように扱いますか。オブジェクトグラフ内を推移的にシリアル化できないようにする必要があります。 Serializableを実装するすべてのオブジェクトを実際にシリアル化することはできません。

<type-def> a = null;

は何が必要なのaが参照するオブジェクトが両方Serializableとして実装していることを確認して、仕様に<type-def>の交換です:

+0

コンパイル時にそれをチェックする方法はありませんか? –

+0

'インタフェースSerializableCollection > {} 'のようなことができますか? –

+1

この 'List'は' Serializable'を実装していないので、 'Serializable'でないオブジェクトの' List'は 'SerializableList'に追加できません。もちろん、シリアライズ可能ではないオブジェクトを含む 'ArrayList'(シリアライズ可能)を追加することもできます。ただし、これを生の型として使用する場合に限ります。それがパラメータ化されている場合、コンパイラはこれについて不平を言うべきです。 – MrD

0

コレクションをクローニングするためのアプローチおよびオブジェクトを含まは

import org.apache.commons.lang3.SerializationUtils; 
... 
ClonedArrayList = SerializationUtils.deserialize(SerializationUtils.serialize(OriginalArrayList)) 

(例えばArrayListの<タイプ>(コレクション)を用い介しSerializationUtilsはSerializableインタフェースを必要とするので)

よろしく、 グンナー

あります