web-dev-qa-db-ja.com

Java:シリアル化できるものとできないもの

Serializable インターフェースが単なる Marker-Interface である場合、Java-私は少し混乱しています:

Javaのシリアル化アルゴリズムのプロセス(メタデータを下から上、次に実際のインスタンスデータを上から下)を読んだ後、どのデータができないかそのアルゴリズムで処理されます。

簡潔かつ形式的に:

  1. どのデータがNotSerializableExceptionを引き起こす可能性がありますか?
  2. クラスにimplements Serializable句を追加することになっていないことをどのように知る必要がありますか?
23
MordechayS

NotSerializableExceptionについて話しているとき、Serializableとしてマークされていないオブジェクトをシリアル化するときにスローされます-シリアル化できないクラスを拡張し、Serializableインターフェイスは完全に問題ありません。

シリアル化できないデータはありません。

8
Michal Borek

まず、クラスのインスタンスをシリアル化する予定がない場合、それをシリアル化することを考える必要さえありません。必要なものだけを実装し、そのためだけにクラスをシリアライズ可能にしようとしないでください。

オブジェクトにシリアル化できないオブジェクトへの参照(推移的または直接)があり、この参照がtransientキーワードでマークされていない場合、オブジェクトはシリアル化できません。

一般に、後でまたはどこかで逆シリアル化するときに再利用できないオブジェクトをシリアル化することは意味がありません。これは、オブジェクトの状態がここでのみ意味がある場合(たとえば、実行中のスレッドへの参照がある場合)、またはソケット、データベース接続などのリソースを使用しているためです。多くのオブジェクトはデータを表していないため、シリアル化することはできません。

13
JB Nizet

Serializableクラスに含まれるSerializable以外のものはすべて、この例外をスローします。 transientキーワードを使用して回避できます。

シリアル化できない一般的な例には、Swingコンポーネントとスレッドが含まれます。あなたがそれについて考えるならば、あなたはそれらをデシリアライズすることは決してできず、理にかなっているので、それは理にかなっています。

5
Daniel Kaplan

すべてのプリミティブデータ型とクラスは、 Serializable を直接拡張します。

class MyClass extends Serializable{
}

または間接的に、

class MyClass extends SomeClass{
}

SomeClassはSerializableを実装しています。

シリアル化できます。 transientとマークされているフィールドを除き、シリアル化可能なクラスのすべてのフィールドはシリアル化されます。直列化可能クラスに直列化可能でないフィールドが含まれる場合(プリミティブではなく、直列化可能インターフェースから拡張されない)、NotSerializableExceptionがスローされます。

2番目の質問への回答:@JBニゼットが言ったように。クラスのインスタンスを何らかのストリームに書き込み、それをSerializableとしてマークする場合は、クラスをSerializableとしてマークしないでください。

4
Sachin Gorade

独自のオブジェクトのシリアル化を処理する必要があります。

Javaがプリミティブデータ型を処理します。

詳細: http://www.tutorialspoint.com/Java/java_serialization.htm

3
Shane

NotSerialisable例外は、シリアライズ可能の何かがシリアライズ可能としてマークされたときにスローされます。そのようなケースの1つは次のとおりです。

class Super{}
class Sub implements Serializable
{
Super super;

ここでは、superはシリアル化可能として言及されていないため、NotSerializableExceptionをスローします。

2
Jain

Javaのシリアル化アルゴリズムのプロセス(メタデータを下から上、次に実際のインスタンスデータを上から下)を読んだ後、そのアルゴリズムで処理できないデータを本当に理解できません。

これに対する答えは、Thread、OutputStream、およびシリアル化できないサブクラスなどの特定のシステムレベルのクラスです。 Oracleのドキュメントで非常によく説明されています: http://www.Oracle.com/technetwork/articles/Java/javaserial-1536170.html

以下は要約です。

一方、Thread、OutputStreamとそのサブクラス、Socketなどの特定のシステムレベルのクラスはシリアル化できません。確かに、そうであったとしても意味がありません。たとえば、JVMで実行されているスレッドはシステムのメモリを使用しています。永続化してJVMで実行しようとしても意味がありません。

1
Vishu Gupta

より現実的には、そのクラスがSerializableインターフェイスを実装しない限り、オブジェクトは(Javaの組み込みメカニズムを介して)シリアル化できません。そのようなクラスのインスタンスであることは十分な条件ではありませんが、オブジェクトを正常にシリアル化するには、保持するすべての非一時的な参照がnullであるか、シリアル化可能なオブジェクトを参照している必要があります。 (これは再帰的な条件であることに注意してください。)プリミティブ値、ヌル、および一時変数は問題ではありません。静的変数は個々のオブジェクトに属さないため、問題も発生しません。

一部の一般的なクラスは、確実にシリアル化に対して安全です。ここではおそらく文字列が最も注目に値しますが、プリミティブ型のすべてのラッパークラスも安全です。プリミティブの配列は確実にシリアル化できます。すべての要素をシリアル化できる場合、参照型の配列をシリアル化できます。

0
Pavan Kumar K

NotSerializableExceptionが発生する可能性のあるデータは何ですか?

Javaでは、オブジェクト(Java既にSerializableインターフェイスを実装しているクラスのインスタンス)をシリアル化します。したがって、クラスはSerializableインターフェイスを実装していません、シリアル化できません(その場合NotSerializableExceptionがスローされます)。

Serializableインターフェースは単なるmarker-interfaceであり、クラスの単なるスタンプであり、JVMに次のように伝えるだけです。クラスはシリアル化できます。

クラスにimplements Serializable句を追加することになっていないことをどのように知る必要がありますか?

それはすべてあなたのニーズ次第です。

  1. Objectをデータベースに保存する場合、バイトシーケンスにシリアル化して、永続データとしてデータベースに保存できます。

  2. Objectをシリアル化して、別のマシンで動作する他のJVMで使用できます。

0