Mengapa writeObject membuang java.io.NotSerializableException dan bagaimana cara memperbaikinya?

110

Saya memiliki pengecualian ini dan saya tidak mengerti mengapa itu akan dibuang atau, bagaimana saya harus menanganinya.

try {
    os.writeObject(element);
} catch (IOException e) {
    e.printStackTrace();
}

Di mana elementa yang TransformGroupberisi beberapa TransformGroupsturunan lain dari kelas Atom:

public class Atom extends Group implements Serializable{
    float pozX,pozY;
    Group group= new Group();   
    Color3f blue = new Color3f(new Color(255));
    Color3f black = new Color3f(new Color(0));
    Sphere AtSph=new Sphere();

    public Atom(final float WEIGHT, final int BOUNDS,final float radius,Color3f color)
    {
        AppSetting ap= new AppSetting(color, black);
        AtSph=new Sphere(radius,1,100,ap);
    }
}

Log kesalahan lengkap:

java.io.NotSerializableException: javax.media.j3d.TransformGroup
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.writeObject(Unknown Source)
    at cls.MolecularBuilder.addAtom(MolecularBuilder.java:511)
    at cls.MolecularBuilder$Console.HidrogenItemActionPerformed(MolecularBuilder.java:897)
    at cls.MolecularBuilder$Console$2.actionPerformed(MolecularBuilder.java:746)
    at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
    at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
    at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
    at javax.swing.AbstractButton.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI.doClick(Unknown Source)
    at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(Unknown Source)
    at java.awt.Component.processMouseEvent(Unknown Source)
    at javax.swing.JComponent.processMouseEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
    at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

AppSetting (di kelas Atom) hanyalah kelas khusus yang memperluas Penampilan.

Mihai Bujanca
sumber
4
Sepertinya javax.media.j3d.TransformGroupitu sendiri tidak menerapkan Serializable
micha
Mengapa Atomkeduanya memperpanjang Groupdan memiliki Groupanggota?
Marquis dari Lorne

Jawaban:

210

Bidang objek Anda pada gilirannya memiliki bidangnya, beberapa di antaranya tidak diimplementasikan Serializable. Dalam kasus Anda, kelas yang melanggar adalah TransformGroup. Bagaimana cara mengatasinya?

  • jika kelas itu milik Anda, buatlah Serializable
  • jika kelasnya adalah pihak ke-3, tetapi Anda tidak membutuhkannya dalam bentuk serial, tandai bidang sebagai transient
  • jika Anda memerlukan datanya dan pihak ketiga, pertimbangkan cara lain untuk serialisasi, seperti JSON, XML, BSON, MessagePack , dll. di mana Anda bisa mendapatkan objek pihak ketiga berseri tanpa mengubah definisinya.
Bozho
sumber
2
Terima kasih banyak, ini akan menjadi hal yang cukup sulit untuk dilakukan, karena objek saya hanya ada sebagai bagian dari TransformGroup, dan tidak ada variabel yang menyimpannya. Aplikasi saya adalah pembangun molekul 3d, dan semua atom serta batas saya baru saja ditambahkan ke TransformGroup sebagai instance- misalnya (Atom baru ()). Masalahnya bukan hanya saya membutuhkannya untuk ditulis ke file, tetapi pengguna mungkin ingin menghapus atau mengedit objek saat ini. Saya pikir saya akan mencoba beberapa serialisasi berbasis XML, tetapi saya cukup baru dalam konsep dan itu agak sulit bagi saya. Terima kasih
Mihai Bujanca
15
Untuk menambah jawaban luar biasa ini: jika Anda membutuhkan datanya dan itu adalah pihak ketiga, Anda mungkin ingin menggabungkan kelas pihak ketiga ke dalam kelas Anda sendiri, yang mengimplementasikan Serializabledan menggunakan readObject()dan writeObject()secara manual membuat serial data dari kelas pihak ketiga. Dalam beberapa kasus, ini mungkin pendekatan yang masuk akal. stackoverflow.com/a/12963580/1208581
sulai
76

java.io.NotSerializableExceptiondapat terjadi ketika Anda membuat serial contoh kelas dalam karena:

serialisasi contoh kelas dalam akan menghasilkan serialisasi contoh kelas luar yang terkait juga

Serialisasi kelas dalam (misalnya, kelas bersarang yang bukan kelas anggota statis), termasuk kelas lokal dan anonim, sangat tidak disarankan

Ref: Antarmuka yang Dapat Disambung

Tho
sumber
5
Ini adalah kasus saya. Itu terjadi ketika saya mengambil jalan pintas pada tes unit. Semoga jawaban ini menghemat waktu orang lain.
pengguna489041
Saya memiliki Set akhir pribadi bidang <ClaimsNode> outgoing = new TreeSet <ClaimsNode> (Pembanding baru <ClaimsNode> () {public int bandingkan (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Vitaly Sazanovich
1
Luar biasa, Secara harfiah saya melakukan ini selama 1 jam terakhir. Saya mulai meragukan bahwa int yang primitif pun tidak dapat diserialkan dan kemudian terpikir oleh saya, bahwa mungkin ada sesuatu yang salah di sini.
Shivam Pokhriyal
13

Buat kelas dapat diserialkan dengan mengimplementasikan antarmuka java.io.Serializable.

  • java.io.Serializable - Marker Interface yang tidak memiliki metode apa pun di dalamnya.
  • Tujuan Antarmuka Penanda - untuk memberi tahu ObjectOutputStreambahwa objek ini adalah objek yang dapat diserialkan.
Prabhakar
sumber
7
Anda dapat membaca pertanyaan, yang sudah menerapkan Serializable. Masih 12+ membuatku takjub.
shaILU