Чому writeObject кидає java.io.NotSerializableException і як це виправити?


110

У мене є цей виняток, і я не розумію, чому це було б кинуто або, як я маю поводитися з цим.

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

Де elementзнайти TransformGroupмістить який -небудь інший TransformGroupsекземпляр класу 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);
    }
}

Повний журнал помилок:

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 (у класі Atom) - це лише спеціальний клас, який розширює зовнішній вигляд.


4
Схоже, javax.media.j3d.TransformGroupсама не реалізує Serializable
micha

Чому Atomобидва подовжуються Groupта мають Groupчлена?
Маркіз Лорн

Відповіді:


210

У свою чергу поля вашого об'єкта мають свої поля, деякі з яких не реалізуються Serializable. У вашому випадку клас правопорушника є TransformGroup. Як це вирішити?

  • якщо клас ваш, складіть його Serializable
  • якщо клас є стороннім, але він вам не потрібен у серіалізованому вигляді, позначте поле як transient
  • якщо вам потрібні його дані та третя сторона, розгляньте інші засоби серіалізації, наприклад JSON, XML, BSON, MessagePack тощо, де ви можете отримати об'єкти сторонніх серіалізованих без зміни їх визначень.

2
Ну, велике спасибі, це буде досить важко зробити, оскільки мої об’єкти існують лише як частина TransformGroup, і немає змінних, які зберігають їх. Моя програма - це тривимірний конструктор молекули, і всі мої атоми та межі просто додаються до TransformGroup як екземпляри, наприклад (новий Atom ()). Проблема полягає не лише в тому, що мені потрібно записати їх у файл, але й у тому, що користувач може захотіти видалити чи редагувати поточні об’єкти. Думаю, я спробую деяку серіалізацію на основі XML, але я зовсім новачок у цій концепції, і мені це поки важко. Дякую
Mihai Bujanca

15
Щоб додати до цієї чудової відповіді: якщо вам потрібні її дані, а це треті сторони, можливо, ви захочете перенести клас третьої сторони у свій клас, який реалізує Serializableта використовує readObject()та writeObject()вручну серіалізує дані стороннього класу. У деяких випадках це може бути розумним підходом. stackoverflow.com/a/12963580/1208581
sulai

76

java.io.NotSerializableExceptionможе статися при серіалізації внутрішнього екземпляра класу, оскільки:

серіалізація такого екземпляра внутрішнього класу призведе до серіалізації відповідного екземпляра зовнішнього класу

Серіалізація внутрішніх класів (тобто вкладених класів, які не є статичними класами членів), включаючи локальні та анонімні класи, сильно не рекомендується

Посилання: Інтерфейс, який можна реалізувати


5
Так було для мене. Це відбувалося, коли я робив скорочення на одиничному тесті. Сподіваюся, що ця відповідь економить когось іншого певний час.
user489041

У мене був полевий приватний кінцевий набір <ClaimsNode> вихідний = новий TreeSet <ClaimsNode> (новий компаратор <ClaimsNode> () {public int порівняння (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Віталій Сазанович

1
Дивовижно, буквально я був у цьому протягом 1 години. Я почав сумніватися, що навіть примітивні вкладки не піддаються серіалізації, і тоді мені спало на думку, що, можливо, тут щось не так.
Шивам Похріял

13

Зробіть серіалізаційний клас, реалізуючи інтерфейс java.io.Serializable.

  • java.io.Serializable - Маркерний інтерфейс, у якому немає ніяких методів.
  • Призначення інтерфейсу маркера - сказати, ObjectOutputStreamщо цей об'єкт є серіалізаційним об'єктом.

7
Ви можете прочитати питання, його вже реалізований Serializable. Ще 12+ мене дивують.
shaILU
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.