Rumah  >  Artikel  >  Java  >  Apakah ralat bersiri Java yang biasa?

Apakah ralat bersiri Java yang biasa?

王林
王林asal
2024-04-16 18:18:01804semak imbas

Ralat bersiri Java biasa termasuk: Konflik versi kelas (InvalidClassException) Tiada superclass boleh bersiri atau antara muka diisytiharkan (NotSerializableException) Akses ditolak atau objek bersiri pantulan haram (IllegalAccessException) Pensirian medan statik boleh diubah atau Rujukan kitaran (keadaan StackOverflowException)

atau tidak konsisten

Apakah ralat bersiri Java yang biasa?

Ralat Pensirian Java Biasa

Ralat Pensirilan Java:

Ralat yang berlaku semasa menukar objek kepada atau membina semula objek daripada aliran binari. Ia biasanya disebabkan oleh sebab berikut:

1. Konflik versi kelas

Objek yang perlu disiri mestilah serasi dengan versi kelas apabila objek dibina semula. Jika tidak serasi, ralat InvalidClassException akan dilemparkan. . Jika tidak, ia menyebabkan NotSerializableException.
  • 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();
    InvalidClassException 错误。
class NotSerializable {
    // ...
}

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

2. 未声明可序列化的超类或接口

  • 任何可序列化的子类都必须声明其直接超级类或实现的接口也具有可序列化性。否则,它会导致 NotSerializableException
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);

3. 拒绝访问或非法反射

  • 序列化的对象必须具有带有 private 访问修饰符的 writeObjectreadObject 方法。反射访问这些方法会导致 IllegalAccessException
class MyClass implements Serializable {
    private static String staticField;
    
    private String instanceField;

    // ...
}

4. 静态字段的序列化

  • 静态字段不会序列化。如果要序列化它们,请将其声明为瞬态(transient)。
// 可变对象
class MyClass implements Serializable {
    private int mutableField;
    
    // ...
}

// 循环引用
class MyClass1 implements Serializable {
    private MyClass myClass2;

    class MyClass2 implements Serializable {
        private MyClass1 myClass1;
    }
}

5. 可变或循环引用

  • 循环引用会导致 StackOverflowException
  • 3 Akses Ditolak atau Refleksi Haram
🎜🎜🎜Objek bersiri mesti mempunyai writeObject dan readObjectprivate access modifier /code> . Akses reflektif kepada kaedah ini menghasilkan IllegalAccessException. 🎜🎜rrreee🎜🎜4. Pensirian medan statik🎜🎜🎜🎜Medan statik tidak akan bersiri. Jika anda ingin mensirikannya, isytiharkannya sebagai sementara (transient). 🎜🎜rrreee🎜🎜5. Rujukan boleh ubah atau bulat 🎜🎜🎜🎜Rujukan bulat boleh menyebabkan StackOverflowException. Objek boleh ubah boleh membawa kepada keadaan tidak konsisten. 🎜🎜rrreee

Atas ialah kandungan terperinci Apakah ralat bersiri Java yang biasa?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn