ホームページ >Java >&#&チュートリアル >一般的な Java シリアル化エラーとは何ですか?

一般的な Java シリアル化エラーとは何ですか?

王林
王林オリジナル
2024-04-16 18:18:01845ブラウズ

一般的な Java シリアル化エラーは次のとおりです。 クラス バージョンの競合 (InvalidClassException) シリアル化可能なスーパークラスまたはインターフェイスが宣言されていません (NotSerializableException) アクセスが拒否された、または不正なリフレクション シリアル化されたオブジェクト (IllegalAccessException) 静的フィールドのシリアル化が変数または循環参照 (StackOverflowException または矛盾した状態)

一般的な Java シリアル化エラーとは何ですか?

一般的な Java シリアル化エラー

Java シリアル化エラー: オブジェクトを または に変換するときに発生するエラーバイナリ ストリームからオブジェクトを再構築します。通常、これは次の理由によって発生します。

1. クラス バージョンの競合

  • シリアル化する必要があるオブジェクトは、次の場合にクラス バージョンと互換性がある必要があります。オブジェクトが再構築されます。互換性がない場合は、InvalidClassException エラーがスローされます。
class MyClass implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;

    // 省略其他代码...
}

// 序列化对象后修改了 MyClass
MyClass myObject = new MyClass();
myObject.setName("John Doe");

// 将对象序列化到文件
FileOutputStream fos = new FileOutputStream("object.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myObject);
oos.close();

// 更改 MyClass 的 serialVersionUID
MyClass.serialVersionUID = 2L;

// 从文件中读取并反序列化对象
FileInputStream fis = new FileInputStream("object.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
MyClass deserializedObject = (MyClass) ois.readObject();
ois.close();

2. シリアル化可能なスーパークラスまたはインターフェイスが宣言されていません

  • シリアル化可能なサブクラスは、その直接のスーパークラスまたは実装されたインターフェイスもシリアル化可能であると宣言する必要があります。それ以外の場合は、NotSerializableException が発生します。
class NotSerializable {
    // ...
}

class MyClass extends NotSerializable implements Serializable {
    // ...
}

3. アクセス拒否または不正なリフレクション

  • シリアル化されたオブジェクトには、private というアクセス修飾子が必要です。 writeObject メソッドと readObject メソッド。これらのメソッドに反射的にアクセスすると、IllegalAccessException が発生します。
  • class MyClass implements Serializable {
        private void writeObject(ObjectOutputStream oos) throws IOException {
            // ...
        }
    
        private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
            // ...
        }
    }
    
    // 使用反射调用 writeObject
    ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream());
    oos.writeObject(myObject);
    Method m = MyClass.class.getDeclaredMethod("writeObject", ObjectOutputStream.class);
    m.setAccessible(true);
    m.invoke(myObject, oos);

4. 静的フィールドのシリアル化

    静的フィールドはシリアル化されません。それらをシリアル化する場合は、それらを一時的として宣言します (
  • transient)。
  • class MyClass implements Serializable {
        private static String staticField;
        
        private String instanceField;
    
        // ...
    }

5. 可変参照または循環参照

    循環参照により
  • StackOverflowException が発生します。変更可能なオブジェクトは、不整合な状態を引き起こす可能性があります。
  • うわー

以上が一般的な Java シリアル化エラーとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。