java - Serializable で定義されたクラスをシリアル化できないのはなぜですか?
シリアル化可能クラスのフィールドは、クラスが明示的にシリアル化または逆シリアル化されない場合でも、それ自体がシリアル化可能または一時的である必要があります。これは、負荷がかかると、ほとんどの J2EE アプリケーション フレームワークがオブジェクトをディスクにフラッシュし、非一時的でシリアル化不可能なデータ メンバーを持つシリアル化可能とされるオブジェクトがプログラムのクラッシュを引き起こし、攻撃者への扉を開く可能性があるためです。
このルールは、シリアル化不可能なフィールド、およびコレクション フィールドがプライベートではない場合 (外部からシリアル化不可能な値が割り当てられる可能性があるため)、およびクラス内でシリアル化不可能な型が割り当てられている場合に問題を引き起こします。
違反コード例
リーリー
オブジェクトがシリアル化される場合、Java のデフォルトのシリアル化ルールに従って、オブジェクト内のすべてのメンバーがシリアル化される必要があります。つまり、これらのクラスは Serializable を実装する必要があります。
したがって、これを変更するには 2 つの方法があります。1 つは、Address で Serializable インターフェイスを実装することです。もう 1 つは、メンバーがシリアル化されないように
transient
マークを Person のアドレス メンバーに追加することです。address メンバーをシリアル化する必要がある場合、Address クラスも Serializable インターフェイスを実装する必要があります。
リーリーアドレス メンバーをシリアル化する必要がない場合は、transient キーワードを追加できます。その場合、アドレス メンバーはシリアル化されず、値は null になります。以下の通り:
もちろん、他の方法もあります:
たとえば、Externalizable インターフェースを実装し、readExternal(ObjectInput in) メソッドと writeExternal(ObjectOutput out) メソッドをオーバーライドします。
Externalizableinterface メソッドの代替実装もあり、あるいは writeObject(ObjectOutputStream obs) メソッドと readObject(ObjectInputStream ois) メソッドを追加して Serializableinterface を実装することもできます。
シリアル化するために、Address が
Serializable を実装する必要があるのか、または transient キーワード person を追加する必要がある理由をもう一度教えてください。 まず、
ObjectOutputStreamObjectOutputStreamを使用してオブジェクトを処理せずに永続化することによってスローされる例外を見てみましょう リーリー
ソースコードを見てください: リーリー このことから、書き込まれているオブジェクト型が String、Array、Enum、または Serializable の場合はシリアル化できますが、それ以外の場合は NotSerializableException がスローされることがわかります。また、オブジェクトをシリアル化する場合、現在のオブジェクト自体がシリアル化されるだけでなく、そのオブジェクトによって参照される他のオブジェクトもシリアル化されます。