2011-07-06 7 views
4

不変の親クラスAがfinalではなく、別のクラスBがそれを拡張する(Bが変更可能です)場合、シリアル化のためにAの不変性が影響を受ける可能性はありますか?Java:不変性とシリアライゼーション

オブジェクトをシリアル化し、プログラムの状態を変更した後、逆シリアル化するための小さなプログラムを作成しました。私はそれがシリアル化された形でオブジェクトを戻しました。だから私はそれを直列化することによってAの不変性を変更することができる方法はあるのだろうか?

答えて

5

それはあなたが求めているものによります。あなたが入れているものとは異なる値を返そうとするなら、あなたはそれを直列化によって行うことができます。シリアル化されたデータは、メモリに存在するAのインスタンスから完全に切り離されます。 Javaは、シリアル化されたデータからオブジェクトを再構築するとき、そのデータの作成に使用された元のAのインスタンスについては何も知らないか、気にしません。シリアライズされた情報で提供されている青写真に基づいてメモリ内にデータ構造を構築するだけです。

したがって、Aを再構築するときに取得する内容を変更するには、バイナリのシリアル化されたデータを手動で変更します。これを行うには、Javaのシリアライズフォーマットをよく理解する必要がありますが、確かに実行できます。

Aの元のインスタンスをシリアル化によって変更する方法があるかどうかを尋ねる場合は(値を変更するために同じオブジェクトを何らかの形で取得するために、逆シリアル化を使用して新しいインスタンスを作成せずに)いいえ、できません。シリアライゼーションは、オブジェクトの現在の状態のスナップショットを作成するだけです。逆シリアル化は、ソースインスタンスから完全に切り離された新しいオブジェクトインスタンスを作成します。そのため、値を手動で変更することもできますが、新しい値を持つ新しいオブジェクトは、逆シリアル化された後でも変更できません。

Aのインスタンスをシリアル化し、次にAクラスのインスタンスとして識別するデータとしてデシリアライズする方法があるかどうかを尋ねているが、その場合も、その答えは「いいえ」です。シリアライズされたデータは、どのクラスのオブジェクトが表現されているかを指定しますが、クラス定義自体はシリアル化されません。したがって、Aのインスタンスをシリアル化してから、変更可能なクラスBのインスタンスを逆シリアル化するように、指定されたクラスを変更することはできますが、それはAの変更可能なインスタンスを取得することと同じではありません。

2

不変性を変更することはできません(クラスは変更できません)が、シリアル化された情報を編集することによって値を変更できます。

あなたはまた、リフレクションによって変更することができます。不変の変更は、魔法の保護ではなく、プログラムの安定性を向上させるミューテータなしのクラスを作成するだけです。変数はおそらく最終的なものでなければならないが、それは必要ではない。不変であるためには、すべてのメソッドに対して常に同じ値を返さなければならない。

もしあなたが不変クラスを拡張しようとするならば、おそらくあなたの拡張も同様に不変であることを望むでしょう - あなたが本当にクラスを拡張したくない場合はおそらくそれをカプセル化したいでしょう(is-a関係かhas-aですか?)

0

オブジェクトをシリアル化するとき、そのオブジェクトは、不変であるかどうかを変更しません。

新しいオブジェクトをデシリアライズすると、記録された情報とデシリアライゼーションの仕方に基づいて最初のオブジェクトが再構成されます。

例えば、不変クラスを持ち、フィールドが一時的である場合、非直列化コピーはそのフィールドセットを持たない(一時的にした)

関連する問題