NotSerializableException - PullRequest
       27

NotSerializableException

1 голос
/ 07 января 2012

По сути, я написал программу, которая рисует фигуры на экране и сохраняет каждую фигуру в ArrayList. Что я хочу сделать, так это выяснить, как сохранить ArrayList в файл, чтобы я мог вызвать его позже и редактировать уже существующие фигуры.

Так что у меня возникли проблемы с выяснением, почему именно я продолжаю получать NotSerializableException, когда уже сделал сериализованный объект Shape уже доступным.

Ниже приведена часть моего кода для сохранения и объект 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)

Ответы [ 2 ]

3 голосов
/ 07 января 2012

Исходя из звонка, который вы делаете на repaint() в Shape, я предполагаю, что это во внутреннем классе. Поэтому у него есть скрытая переменная, ссылающаяся на включающий его экземпляр. Он попытается сериализовать этот объект вместе с самим собой. Сериализуем ли внешний класс? Или еще лучше, можно ли сделать Shape обычным классом высшего уровня?

1 голос
/ 19 августа 2014

Чтобы избежать NotSerializableException, убедитесь, что:

  1. ваш класс реализует Сериализуемый
  2. все не примитивные члены реализуют Сериализуемый (или вместо этого временный)
  3. если ваш класс является внутренним классом , он либо статический, либо реализует внешний класс Сериализуемый

Кроме того, вам также необходимо определить serialVersionUID для каждого класса Serializable. Проверьте все 3 случая выше плюс:

  1. все Сериализуемые суперклассы
  2. если ваш класс анонимный класс , определите его там тоже

Примечание: ваш код может иногда выполняться без serialVersionUID, но прочитайте последний абзац в javadoc Serializable , чтобы понять, почему это будет проблемой в зависимости от среды.


Существует опция виртуальной машины для добавления деталей к исключению. Он показывает, что корневые и вложенные классы не могут сериализоваться:

-Dsun.io.serialization.extendedDebugInfo=true
...