ทำไม writeObject ถึงโยน java.io.NotSerializableException และฉันจะแก้ไขได้อย่างไร


111

ฉันมีข้อยกเว้นนี้และฉันไม่เข้าใจว่าทำไมมันถึงถูกโยนทิ้งหรือฉันควรจัดการอย่างไร

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สมาชิก?
Marquis of Lorne

คำตอบ:


211

Serializableเขตข้อมูลของวัตถุของคุณได้ในการเปิดสาขาของพวกเขาบางส่วนที่ไม่ได้ใช้ TransformGroupในกรณีของคุณชั้นที่กระทำผิดคือ ต้องแก้ยังไง?

  • ถ้าชั้นเรียนเป็นของคุณทำให้มัน Serializable
  • หากชั้นเรียนเป็นบุคคลที่สาม แต่คุณไม่จำเป็นต้องใช้ในรูปแบบอนุกรมให้ทำเครื่องหมายที่ฟิลด์เป็น transient
  • หากคุณต้องการข้อมูลและเป็นของบุคคลที่สามให้พิจารณาวิธีอื่น ๆ ในการทำให้เป็นอนุกรมเช่น JSON, XML, BSON, MessagePackเป็นต้นซึ่งคุณจะได้รับออบเจ็กต์ของบุคคลที่สามต่อเนื่องโดยไม่ต้องแก้ไขคำจำกัดความ

2
ขอบคุณมากมันจะค่อนข้างยากที่จะทำเนื่องจากวัตถุของฉันมีอยู่เป็นส่วนหนึ่งของ TransformGroup เท่านั้นและไม่มีตัวแปรใด ๆ ที่เก็บไว้ แอปของฉันเป็นตัวสร้างโมเลกุล 3 มิติและเพิ่งเพิ่มอะตอมและขอบเขตทั้งหมดไปยัง TransformGroup เป็นอินสแตนซ์เช่น (Atom ใหม่ ()) ปัญหาไม่เพียง แต่ฉันต้องการให้พวกเขาเขียนลงในไฟล์ แต่ผู้ใช้อาจต้องการลบหรือแก้ไขวัตถุปัจจุบัน ฉันคิดว่าฉันจะลองอนุกรมตาม XML แต่ฉันค่อนข้างใหม่สำหรับแนวคิดนี้และมันก็ค่อนข้างยากสำหรับฉัน ขอบคุณ
Mihai Bujanca

15
หากต้องการเพิ่มคำตอบที่ยอดเยี่ยมนี้: หากคุณต้องการข้อมูลและเป็นของบุคคลที่สามคุณอาจต้องการรวมคลาสของบุคคลที่สามไว้ในคลาสของคุณเองซึ่งดำเนินการSerializableและใช้งานreadObject()และwriteObject()จัดลำดับข้อมูลของคลาสบุคคลที่สามด้วยตนเอง ในบางกรณีนี่อาจเป็นแนวทางที่สมเหตุสมผล stackoverflow.com/a/12963580/1208581
sulai

76

java.io.NotSerializableExceptionสามารถเกิดขึ้นได้เมื่อคุณทำให้อินสแตนซ์คลาสภายในเป็นอนุกรมเนื่องจาก:

การจัดลำดับอินสแตนซ์คลาสภายในดังกล่าวจะทำให้เกิดการทำให้เป็นอนุกรมของอินสแตนซ์คลาสภายนอกที่เกี่ยวข้องเช่นกัน

การทำให้เป็นลำดับชั้นของคลาสภายใน (เช่นคลาสซ้อนที่ไม่ใช่คลาสสมาชิกแบบคงที่) รวมถึงคลาสโลคัลและคลาสที่ไม่ระบุชื่อเป็นสิ่งที่ ไม่ควรอย่างยิ่ง

อ้างถึงอินเทอร์เฟซที่ต่ออนุกรมได้


5
นี่เป็นกรณีของฉัน มันเกิดขึ้นเมื่อฉันทำการทดสอบหน่วยสั้น ๆ หวังว่าคำตอบนี้จะช่วยคนอื่นได้บ้าง
user489041

ฉันมีฟิลด์ส่วนตัวสุดท้าย Set <ClaimsNode> outgoing = TreeSet ใหม่ <ClaimsNode> (ตัวเปรียบเทียบใหม่ <ClaimsNode> () {การเปรียบเทียบ int สาธารณะ (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Vitaly Sazanovich

1
น่าทึ่งจริงๆฉันอยู่ในนี้มา 1 ชั่วโมงแล้ว ฉันเริ่มสงสัยว่าแม้แต่ ints ดั้งเดิมก็ไม่สามารถต่ออนุกรมกันได้แล้วมันก็เกิดขึ้นกับฉันว่าบางทีมีบางอย่างผิดปกติที่นี่
Shivam Pokhriyal

13

ทำให้ serializable java.io.Serializableชั้นเรียนโดยการใช้อินเตอร์เฟซ

  • java.io.Serializable - Marker Interface ซึ่งไม่มีวิธีการใด ๆ
  • วัตถุประสงค์ของส่วนต่อประสานเครื่องหมาย - เพื่อบอกObjectOutputStreamว่าวัตถุนี้เป็นวัตถุที่ต่อเนื่องกันได้

8
คุณสามารถอ่านคำถามซึ่งมีการใช้ Serializable อยู่แล้ว ยัง 12+ ทำให้ฉันประหลาดใจ
shaILU
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.