Java の Java.IO.NotSerializableException を修正
-
Java で
java.io.NotSerializableExceptionを再現する -
Java での
java.io.NotSerializableExceptionの原因 -
Java の
java.io.NotSerializableExceptionを修正
今日は、Javaでプログラムを書いているときにjava.io.NotSerializableExceptionを再現します。 また、このエラーが何を意味するのかを理解し、その原因と解決策を導きます。
Java で java.io.NotSerializableException を再現する
コード例 (Student.java ファイル):
package com.serializertest;
class Student {
private String studentId;
public String getId() {
return studentId;
}
public void setId(String id) {
this.studentId = id;
}
}
Student クラスは、studentId というメンバー変数を持つヘルパー クラスです。 また、学生の id を取得および設定するための getId() および setId() というメンバー メソッドもあります。
サンプルコード (SerializerTest.java ファイル):
package com.serializertest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializerTest {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("students.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
Student student = new Student();
student.setId("0001");
objectOutputStream.writeObject(student);
objectOutputStream.close();
}
}
SerializerTest は、main() ドライバー メソッドを持つメイン クラスです。 main() 内で、ファイルを作成するために FileOutputStream クラスのインスタンスを作成します。
同様に、ObjectOutputStream クラスの別のインスタンスを作成します。
次に、Student クラスのオブジェクトを作成し、文字列引数を渡してその setId() メソッドを呼び出します。 次に、ObjectOutputStream クラスのオブジェクトを使用して、オブジェクトをストリームに書き込みます。
そのために、writeObject() メソッドを使用しています。
その後、close() メソッドを使用してストリームを閉じ、プログラムを実行しますが、プログラムの出力コンソールに次の 例外 が表示されます。
Exception in thread "main" java.io.NotSerializableException: com.serializertest.Student
なぜ私たちはこれに直面しているのですか? エラーを理解して、以下の原因を見つけてみましょう。
Java での java.io.NotSerializableException の原因
原因を見つけるには、NotSerializableException と Serialization を理解することが不可欠です。
シリアル化は、オブジェクトの状態をバイト ストリームに書き込むために使用する Java プログラミングのメカニズムです。 これに対し、その逆の操作をデシリアライズと呼ぶ。
Serialization と Deserialization はプラットフォームに依存しません。 これは、両方のプロセスを異なるプラットフォームで実行できることを意味します。
私たちは、Remote Method Invocation (RMI) と Enterprise Java Beans (EJB) で Serialization を使用しています。 Java Persistence API (JPA)、Hibernate などでも使用されます。
NotSerializableException は、オブジェクト ストリーム クラスに固有の他のすべての例外のスーパークラスとして定義される ObjectStreamException クラスを拡張する例外です。
さらに、ObjectStreamException は IOException を拡張し、I/O 例外が生成されたことをさらに通知します。
これで、Java の Serialization と NotSerializableException がわかりました。 この議論により、Java での NotSerializableException の理由を発見することができます。
- クラスのインスタンスが
Serializableインターフェイスを実装する必要がある場合、NotSerializableExceptionが発生します。 - この例外は、クラスのインスタンスまたはシリアライゼーション ランタイムでも発生します。
NotSerializableExceptionの引数はクラスの名前であることを思い出してください。 - ドキュメント によると、完全なオブジェクト グラフはシリアライズ可能である必要があります。
NotSerializableExceptionは、クラスのインスタンスをシリアル化しようとしたときに、フィールドの少なくとも 1つがSerializableインターフェイスを実装していない場合にも発生します。
Java の java.io.NotSerializableException を修正
次の解決策を使用して、Java の java.io.NotSerializableException を修正できます。
-
この例外を
throwsするクラスを見つけ、Serializableインターフェースを実装してSerializableにします。NotSerializableExceptionをスローするクラスがサードパーティ ライブラリに属している場合、このソリューションは適切な選択ではない可能性があることに注意してください。 -
クラスがシリアライズ可能でないオブジェクトを参照する場合、これらのオブジェクトがシリアライズ可能であってはならない場合、オブジェクトを
transientとして宣言できます。 問題は、なぜそれをtransientと宣言するのかということです。これは、
transientとして宣言されたクラスのフィールドがシリアライズ可能なランタイムによって無視され、例外が発生しないためです。 -
そのデータとそのサード パーティが必要な場合は、シリアル化の他の手段を検討できます。 たとえば、定義を変更せずにサードパーティ オブジェクトをシリアル化できる XML、JSON など。
私たちの場合、Serializable を実装すると、java.io.NotSerializableException が修正されました。 次のコード例を参照してください。
コード例 (Students.java ファイル):
package com.serializertest;
import java.io.Serializable;
class Student implements Serializable {
private String studentId;
public String getId() {
return studentId;
}
public void setId(String id) {
this.studentId = id;
}
}
サンプルコード (SerializerTest.java ファイル):
package com.serializertest;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
public class SerializerTest {
public static void main(String[] args) throws IOException {
FileOutputStream fileOutputStream = new FileOutputStream("students.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
Student student = new Student();
student.setId("0001");
objectOutputStream.writeObject(student);
objectOutputStream.close();
}
}
