基本上,我编写了一个程序,在屏幕上绘制形状,并将每个形状保存到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(p.x <= center.x + radius && p.x >= center.x - radius && p.y <= center.y + radius && p.y >= 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)
答案 0 :(得分:3)
根据你在Shape中对repaint()
进行的调用,我猜它是在内部类中。因此它有一个引用其封闭实例的隐藏变量。它将尝试将该对象与其自身序列化。外层类是否可序列化?或者更好的是,Shape可以变成普通的顶级课程吗?
答案 1 :(得分:1)
要避免NotSerializableException,请确保:
除此之外,您还需要为每个Serializable类定义 serialVersionUID 。检查以上所有3个案例加上:
注意:您的代码有时可以在没有serialVersionUID的情况下运行,但read the last paragraph in Serializable's javadoc可以了解为什么它会成为问题,具体取决于环境。
有一个VM选项可以向异常添加详细信息。它显示了无法序列化的根和嵌套类:
-Dsun.io.serialization.extendedDebugInfo=true