Tại sao writeObject lại ném java.io.NotSerializableException và làm cách nào để khắc phục lỗi này?


110

Tôi có ngoại lệ này và tôi không hiểu tại sao nó lại bị ném hoặc, tôi nên xử lý nó như thế nào.

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

Trong trường hợp elementlà một TransformGroupcó chứa một số khác TransformGroupsmột thể hiện của Atom lớp:

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);
    }
}

Nhật ký lỗi đầy đủ:

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 (trong lớp Atom) chỉ là một lớp tùy chỉnh mở rộng Giao diện.


4
Có vẻ như javax.media.j3d.TransformGroupbản thân nó không triển khai Serializable
micha

Tại sao Atomcả hai đều mở rộng Groupvà có một Groupthành viên?
Marquis of Lorne

Câu trả lời:


210

Các trường đối tượng của bạn lần lượt có các trường của chúng, một số trường không triển khai Serializable. Trong trường hợp của bạn, lớp vi phạm là TransformGroup. Làm thế nào để giải quyết nó?

  • nếu lớp học là của bạn, hãy làm cho nó Serializable
  • nếu lớp là của bên thứ 3, nhưng bạn không cần nó ở dạng tuần tự, hãy đánh dấu trường là transient
  • nếu bạn cần dữ liệu của nó và đó là bên thứ ba, hãy xem xét các phương tiện tuần tự hóa khác, như JSON, XML, BSON, MessagePack , v.v. nơi bạn có thể nhận các đối tượng của bên thứ ba được tuần tự hóa mà không cần sửa đổi định nghĩa của chúng.

2
Chà, cảm ơn rất nhiều, sẽ là một việc khá khó thực hiện, vì các đối tượng của tôi chỉ tồn tại như một phần của TransformGroup và không có bất kỳ biến nào lưu trữ chúng. Ứng dụng của tôi là một trình xây dựng phân tử 3d và tất cả các nguyên tử và giới hạn của tôi chỉ được thêm vào TransformGroup dưới dạng các phiên bản - ví dụ: (Atom ()) mới. Vấn đề không chỉ là tôi cần chúng được ghi vào một tệp, mà là người dùng có thể muốn xóa hoặc chỉnh sửa các đối tượng hiện tại. Tôi nghĩ rằng tôi sẽ thử một số tuần tự hóa dựa trên XML, nhưng tôi còn khá mới với khái niệm này và nó còn hơi khó đối với tôi. Cảm ơn bạn
Mihai Bujanca 15/12/12

15
Để thêm vào câu trả lời tuyệt vời này: nếu bạn cần dữ liệu của nó và đó là bên thứ ba, bạn có thể muốn bọc lớp của bên thứ ba vào lớp của riêng bạn, lớp này sẽ triển khai Serializablevà sử dụng readObject()writeObject()để tuần tự hóa dữ liệu của lớp bên thứ ba theo cách thủ công. Trong một số trường hợp, đây có thể là một cách tiếp cận hợp lý. stackoverflow.com/a/12963580/1208581
sulai

76

java.io.NotSerializableExceptioncó thể xảy ra khi bạn tuần tự hóa một cá thể lớp bên trong vì:

việc tuần tự hóa một cá thể lớp bên trong như vậy cũng sẽ dẫn đến việc tuần tự hóa cá thể lớp bên ngoài được liên kết của nó

Việc tuần tự hóa các lớp bên trong (tức là các lớp lồng nhau không phải là các lớp thành viên tĩnh), bao gồm các lớp cục bộ và ẩn danh, không được khuyến khích

Tham khảo: Giao diện có thể nối tiếp hóa


5
Đây là trường hợp của tôi. Nó đã xảy ra khi tôi thực hiện một bài kiểm tra ngắn hạn. Hy vọng câu trả lời này tiết kiệm thời gian cho người khác.
dùng489041

Tôi đã có một trường private final Set <ClaimsNode> outgoing = new TreeSet <ClaimsNode> (new Comparator <ClaimsNode> () {public int so sánh (ClaimsNode o1, ClaimsNode o2) {return o1.getNativeIndex () - o2.getNativeIndex (); }});
Vitaly Sazanovich,

1
Thật tuyệt vời, theo nghĩa đen, tôi đã quan tâm đến điều này trong 1 giờ qua. Tôi bắt đầu nghi ngờ rằng ngay cả các int nguyên thủy cũng không thể tuần tự hóa và sau đó tôi chợt nhận ra rằng có lẽ điều gì đó thực sự không ổn ở đây.
Shivam Pokhriyal

13

Làm cho lớp có thể tuần tự hóa bằng cách triển khai giao diện java.io.Serializable.

  • java.io.Serializable - Giao diện Marker mà không có bất kỳ phương thức nào trong đó.
  • Mục đích của Giao diện Marker - để nói ObjectOutputStreamrằng đối tượng này là một đối tượng có thể tuần tự hóa.

7
Bạn có thể đọc câu hỏi, câu hỏi đã được triển khai Serializable. Vẫn còn 12+ làm tôi ngạc nhiên.
shaILU
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.