2010-12-15 9 views
6

私は、一般的に抽象クラスをJavaでシリアライズ可能にするべきではないことを読んでいます。サブクラスは直列化可能である必要があります(例えば、抽象クラスにフィールドがある場合はカスタム読み込み、書き込みメソッドが必要です)。なぜJavaで抽象クラスを直列化しないのですか?

この理由は何ですか?なぜそれは悪いデザインと見なされますか?

Update1:​​私はいくつかのフィールドと3つのサブクラスを持つ抽象クラスを持っています。今のところ、私は次のアプローチを使用しています。

私はすべてのサブクラスをカスタムの読み込み、書き込みメソッドでシリアライズ可能にしました。抽象クラスで私は以下のメソッドを持っています。カスタム読み取りで

void writeFields(ObjectOutputStream out)throws IOException { .... } 

void readFields(ObjectInputStream in) throws IOException, ClassNotFoundException{ ... } 

、私は抽象クラスのフィールドをシリアル化(デ)にこれらのメソッドを呼び出して、サブクラスのメソッドを記述します。このアプローチは正しいですか?それとももっと良いアプローチがありますか?

更新2:私はTomのアドバイスを受けて、抽象クラスSerializableを作成しました。 (私はすべてのサブクラスをシリアライズ可能にしたいと思います。抽象クラスにデータがあります)これは脇にありますが、使用している記事を完成させるだけです。reflection to change final fields as advised by Jeremy Manson.

+0

この質問はすべてのオブジェクト指向言語に適用されます。 –

答えて

1

それは必ずしも悪いデザインであることはわかりません。シリアライゼーションは事実上実装上の問題です(Josh Blochは私に同意しません)ので、インタフェースには意味がありません。抽象クラスに状態がある場合は、それを直列化可能にする必要があります。それが国家を持っていなければ、そうする理由は全くありません。

例を考えてみましょう。 java.security.cert.Certificateは、逐次処理可能な抽象クラスであり、"type"の直列化可能フィールドを持ちます。直列化できない場合は、サブクラスが直列化可能で、そのフィールドを設定することはできません。あなたはハックを余儀なくされます。

java.io.Serializableはハックです。インターフェイスであってはなりません。アノテーション(またはtransientのような言語の進化)がより適切であったでしょう。

いつものように、継承を優先して、ランダムなクラスを直列化できないようにすることをお勧めします。

+0

最新の質問をご覧ください。 – athena

+0

@athenaあなたは実際にAPIのようなメソッドを望んでいません。 –

+0

なぜですか?すべてのサブクラスをSerializableにしたい。抽象クラスにはフィールドがあります。このような状況では、抽象クラスをSerializable(カスタムの読み書きメソッドを使用して)にする方が良いでしょうか? – athena

3

オブジェクトをデシリアライズする場合、その型は何ですか?

定義により、抽象クラスはインスタンス化できません。それを直列化することができれば、逆シリアル化することもでき、抽象クラスのインスタンスを得ることができます。これは抽象クラスの定義と矛盾し、したがって実行できません。

+0

+1は同じことをちょっと違うと言っていましたが、あなたの答えは私が言っていたよりもはるかに簡潔に示しています。 –

+3

オブジェクトを逆シリアル化した場合、そのクラスは直列化されたオブジェクトと同じになります( 'writeReplace' /' readResolve'を与えたり取ったりします)。 –

+1

私はあなたの議論に欠陥があると信じています。抽象クラスをインスタンス化することはできません。したがって、抽象クラスの直列化を解除する必要はありません。抽象クラスの非直列化は、派生した具象クラスのコンテキスト内にあります。つまり、クラスは逆直列化の時点で認識されています。 – DwB

5

私は、抽象クラスがSerializableを実装している場合、サブタイプを直列化できないようにする方法がないと考えています。各コンクリートタイプがそれ自体のために宣言するのがよい...

+0

+1。コレクションAPIはそのための良い例です。 – Bozho

+0

すべてのサブクラスをSerializableにしたい。抽象クラスにはフィールドがあります。このような状況では、抽象クラスをSerializableにする方が良いでしょうか? – athena

+0

コレクションフレームワークを見て - no;)AbstractListはシリアライズ可能ではありません。とにかくそれほど大きな違いはありません。 – Bozho

0

これは強制的な決定であるため、唯一の設計ではありません。直列化できないメンバーを持つサブクラスが必要な場合はどうなりますか?

それが理由です。

など。リストはシリアライズ可能ではありませんが、メジャーリストの実装はすべてです。(私はリストがインターフェイスだと知っていますが、メンバーのない抽象クラス=/=インターフェイス)

関連する問題