Perché writeObject genera java.io.NotSerializableException e come la risolvo?


110

Ho questa eccezione e non capisco perché verrebbe lanciata o come dovrei gestirla.

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

Dov'è elementun TransformGroupcontenente qualche altra TransformGroupsistanza della classe 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);
    }
}

Il registro degli errori completo:

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 (nella classe Atom) è solo una classe personalizzata che estende l'aspetto.


4
Sembra che di per javax.media.j3d.TransformGroupsé non implementa Serializable
micha

Perché Atomentrambi si estendono Groupe hanno un Groupmembro?
Marchese di Lorne

Risposte:


210

I campi del tuo oggetto hanno a loro volta i loro campi, alcuni dei quali non implementano Serializable. Nel tuo caso la classe offensiva è TransformGroup. Come risolverlo?

  • se la classe è tua, fallo Serializable
  • se la classe è di terze parti, ma non è necessaria nel modulo serializzato, contrassegnare il campo come transient
  • se hai bisogno dei suoi dati ed è di terze parti, considera altri mezzi di serializzazione, come JSON, XML, BSON, MessagePack , ecc. dove puoi ottenere oggetti di terze parti serializzati senza modificare le loro definizioni.

2
Bene, grazie mille, sarà piuttosto difficile da fare, poiché i miei oggetti esistono solo come parte del TransformGroup e non ci sono variabili che li memorizzano. La mia app è un generatore di molecole 3d e tutti i miei atomi e limiti vengono aggiunti al TransformGroup come istanze, ad esempio (new Atom ()). Il problema non è solo che ho bisogno che vengano scritti su un file, ma che l'utente potrebbe voler rimuovere o modificare gli oggetti correnti. Penso che proverò un po 'di serializzazione basata su XML, ma sono abbastanza nuovo al concetto ed è ancora un po' difficile per me. Grazie
Mihai Bujanca

15
Per aggiungere a questa eccellente risposta: se hai bisogno dei suoi dati ed è di terze parti, potresti voler avvolgere la classe di terze parti nella tua classe, che implementa Serializablee utilizza readObject()e writeObject()per serializzare manualmente i dati della classe di terze parti. In alcuni casi questo potrebbe essere un approccio ragionevole. stackoverflow.com/a/12963580/1208581
Sulai

76

java.io.NotSerializableExceptionpuò verificarsi quando serializzi un'istanza di una classe interna perché:

serializzare un'istanza di classe interna di questo tipo comporterà anche la serializzazione dell'istanza di classe esterna associata

La serializzazione delle classi interne (cioè, classi annidate che non sono classi membri statiche), comprese le classi locali e anonime, è fortemente sconsigliata

Rif: l'interfaccia serializzabile


5
Questo è stato il caso per me. Stava accadendo quando ho preso una scorciatoia su uno unit test. Spero che questa risposta faccia risparmiare tempo a qualcun altro.
user489041

Avevo un campo privato finale Set <ClaimsNode> outgoing = new TreeSet <ClaimsNode> (new Comparator <ClaimsNode> () {public int compare (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Vitaly Sazanovich

1
Incredibile, letteralmente sono stato coinvolto in questo per 1 ora. Ho iniziato a dubitare che anche gli int primitivi non fossero serializzabili e poi mi è venuto in mente che forse qualcosa non va davvero qui.
Shivam Pokhriyal

13

Rendi serializzabile la classe implementando l'interfaccia java.io.Serializable.

  • java.io.Serializable - Marker Interface che non ha alcun metodo al suo interno.
  • Scopo dell'interfaccia Marker - per indicare ObjectOutputStreamche questo oggetto è un oggetto serializzabile.

7
Puoi leggere la domanda, sta già implementando Serializable. Ancora 12+ mi stupiscono.
shaILU
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.