NotSerializableException

基本上,我编写了一个程序,在屏幕上绘制形状,并将每个形状保存到ArrayList中。 我想要做的是弄清楚如何将ArrayList保存到文件中,以便我可以稍后再调用它并编辑已存在的形状。

因此,当我使对象Shape可序列化时,我一直在弄清楚为什么我一直得到一个NotSerializableException。

下面是我的代码的保存部分和Shape对象。

save.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ int returnVal = fc.showSaveDialog(BallWorld.this); if(returnVal == JFileChooser.APPROVE_OPTION){ File file = fc.getSelectedFile(); ArrayList list = bp.shapes; FileOutputStream fos = null; ObjectOutputStream oos = null; try{ fos = new FileOutputStream(file); oos = new ObjectOutputStream(fos); oos.writeObject(list); oos.close(); } catch(IOException ex){ ex.printStackTrace(); } } } }); 

  public class Shape implements Serializable{ int radius; Point center; Color color; int sides; Polygon shape; public Shape(int _radius, Point _center, Color _color, int _sides){ radius = _radius; center = _center; color = _color; sides = _sides; } public void draw(Graphics g){ Graphics2D g2d = (Graphics2D) g; g2d.setColor(color); shape = new Polygon(); if(sides != 0 && sides != 4){ if(sides % 2 == 0){ if(sides / 2 % 2 == 0){ for(int i = 0; i < sides; i++){ shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides - Math.PI / sides)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides - Math.PI / sides))); } } else if(sides / 2 % 1 == 0){ for(int i = 0; i < sides; i++){ shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides))); } } } else{ for(int i = 0; i < sides; i++){ shape.addPoint((int) (center.x + radius * Math.cos(i * 2 * Math.PI / sides - Math.PI / 2)), (int) (center.y + radius * Math.sin(i * 2 * Math.PI / sides - Math.PI / 2))); } } g2d.fillPolygon(shape); } else if(sides == 4){ g2d.fillRect(center.x - radius, center.y - radius, radius * 2, radius * 2); } else{ g2d.fillOval(center.x - radius, center.y - radius, radius * 2, radius * 2); } repaint(); } public boolean contains(Point p){ if(sides == 0){ if(center.distance(p) <= radius){ return true; } } else if(sides == 4){ if(px = center.x - radius && py = center.y - radius){ return true; } } else{ if(shape.contains(p)){ return true; } } return false; } } 

 java.io.NotSerializableException: javax.swing.plaf.basic.BasicFileChooserUI$AcceptAllFileFilter at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeArray(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source) at javax.swing.JComboBox.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source) at javax.swing.JLabel.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeArray(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at javax.swing.ArrayTable.writeArrayTable(Unknown Source) at javax.swing.JComponent.writeObject(Unknown Source) at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.defaultWriteObject(Unknown Source) at java.awt.Window.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at java.awt.Window.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.defaultWriteFields(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at java.util.ArrayList.writeObject(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at java.io.ObjectStreamClass.invokeWriteObject(Unknown Source) at java.io.ObjectOutputStream.writeSerialData(Unknown Source) at java.io.ObjectOutputStream.writeOrdinaryObject(Unknown Source) at java.io.ObjectOutputStream.writeObject0(Unknown Source) at java.io.ObjectOutputStream.writeObject(Unknown Source) at BallWorld$2.actionPerformed(BallWorld.java:112) 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$000(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.awt.EventQueue$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.security.AccessControlContext$1.doIntersectionPrivilege(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.awt.EventQueue$2.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at java.security.AccessControlContext$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) 

根据你在Shape中调用repaint()的调用,我猜它是在内部类中。 因此它有一个引用其封闭实例的隐藏变量。 它将尝试将该对象与其自身序列化。 外部类是否可序列化? 或者更好的是,Shape可以制作成普通的顶级课程吗?

要避免NotSerializableException,请确保:

  1. 你的类实现了Serializable
  2. 所有非原始成员都实现Serializable(或者是瞬态的)
  3. 如果您的类是内部类,则它是静态的,或者外部类实现Serializable

除此之外,您还需要为每个Serializable类定义serialVersionUID 。 检查以上所有3个案例加:

  1. 所有Seri​​alizable 超类
  2. 如果您的类是匿名类 ,那么也在那里定义它

注意:您的代码有时可以在没有serialVersionUID的情况下运行,但请阅读Serializable的javadoc中的最后一段,以了解为什么它会成为一个问题,具体取决于环境。


有一个VM选项可以向exception添加详细信息。 它显示了无法序列化的根和嵌套类:

 -Dsun.io.serialization.extendedDebugInfo=true