Warum löst writeObject java.io.NotSerializableException aus und wie behebe ich das?

110

Ich habe diese Ausnahme und verstehe nicht, warum sie ausgelöst wird oder wie ich damit umgehen soll.

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

Wo elementist eine TransformGroupandere TransformGroupsInstanz der Klasse 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);
    }
}

Das vollständige Fehlerprotokoll:

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 (in der Atom-Klasse) ist nur eine benutzerdefinierte Klasse, die das Erscheinungsbild erweitert.

Mihai Bujanca
quelle
4
Sieht aus wie javax.media.j3d.TransformGroupselbst nicht Serializable implementiert
micha
Warum Atomverlängern Groupund haben beide ein GroupMitglied?
Marquis von Lorne

Antworten:

210

Die Felder Ihres Objekts haben wiederum ihre Felder, von denen einige nicht implementiert sind Serializable. In Ihrem Fall ist die beleidigende Klasse TransformGroup. Wie man es löst?

  • Wenn die Klasse deine ist, mach es Serializable
  • Wenn die Klasse von Drittanbietern stammt, Sie sie jedoch nicht in serialisierter Form benötigen, markieren Sie das Feld als transient
  • Wenn Sie Daten und Daten von Drittanbietern benötigen, sollten Sie andere Serialisierungsmethoden in Betracht ziehen, z. B. JSON, XML, BSON, MessagePack usw., mit denen Sie Objekte von Drittanbietern serialisieren können, ohne ihre Definitionen zu ändern.
Bozho
quelle
2
Vielen Dank, es wird ziemlich schwierig, da meine Objekte nur als Teil der TransformGroup existieren und es keine Variablen gibt, die sie speichern. Meine App ist ein 3D-Molekül-Builder, und alle meine Atome und Grenzen werden der TransformGroup nur als Instanzen hinzugefügt, z. B. (neues Atom ()). Das Problem ist nicht nur, dass ich sie in eine Datei schreiben muss, sondern dass der Benutzer möglicherweise aktuelle Objekte entfernen oder bearbeiten möchte. Ich denke, ich werde eine XML-basierte Serialisierung ausprobieren, aber ich bin ziemlich neu im Konzept und es ist noch ein bisschen schwierig für mich. Vielen Dank
Mihai Bujanca
15
Um diese hervorragende Antwort zu ergänzen: Wenn Sie die Daten und die Daten von Drittanbietern benötigen, können Sie die Klasse von Drittanbietern in Ihre eigene Klasse einbinden, die die Daten der Klasse von Drittanbietern implementiert Serializableund verwendet readObject()und writeObject()manuell serialisiert. In einigen Fällen kann dies ein vernünftiger Ansatz sein. stackoverflow.com/a/12963580/1208581
Sulai
76

java.io.NotSerializableExceptionkann auftreten, wenn Sie eine Instanz der inneren Klasse serialisieren, weil:

Die Serialisierung einer solchen Instanz der inneren Klasse führt auch zur Serialisierung der zugehörigen Instanz der äußeren Klasse

Von der Serialisierung innerer Klassen (dh verschachtelter Klassen, die keine statischen Mitgliedsklassen sind), einschließlich lokaler und anonymer Klassen, wird dringend abgeraten

Ref: Die serialisierbare Schnittstelle

Tho
quelle
5
Dies war bei mir der Fall. Es geschah, als ich eine Abkürzung für einen Unit-Test machte. Hoffe, diese Antwort spart jemand anderem etwas Zeit.
user489041
Ich hatte ein Feld private final Set <ClaimsNode> outgoing = new TreeSet <ClaimsNode> (neuer Komparator <ClaimsNode> () {public int compare (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Vitaly Sazanovich
1
Erstaunlich, ich war buchstäblich die letzte Stunde damit beschäftigt. Ich begann zu bezweifeln, dass selbst primitive Ints nicht serialisierbar sind, und dann kam mir der Gedanke, dass hier vielleicht etwas wirklich nicht stimmt.
Shivam Pokhriyal
13

Machen Sie die Klasse serialisierbar, indem Sie die Schnittstelle implementieren java.io.Serializable.

  • java.io.Serializable - Marker-Schnittstelle, die keine Methoden enthält.
  • Zweck der Markierungsschnittstelle - um anzuzeigen, ObjectOutputStreamdass dieses Objekt ein serialisierbares Objekt ist.
Prabhakar
quelle
7
Sie können Frage lesen, es ist bereits Serializable implementiert. Immer noch 12+ überraschen mich.
ShaILU