Java可序列化问题

Java可序列化问题,java,swing,ioexception,serializable,Java,Swing,Ioexception,Serializable,我试图在我的程序中序列化我的模型。该模型名为“ImageModel”,它实现了Serializable。此模型还包含另一个名为“Perspective”的自定义对象,该对象还实现了可序列化的。我有一个静态实用程序类,它序列化并读取我的模型。这段代码已经用一个“ImageModel”在main方法中进行了测试,一切都很正常 但当我试图在实际程序中使用它时,我遇到了一个问题。“ImageModel”类在我的系统类中声明,名为“MainWindow”,它扩展了JFrame,是大多数不同类之间的链接。由

我试图在我的程序中序列化我的模型。该模型名为“
ImageModel
”,它实现了
Serializable
。此模型还包含另一个名为“
Perspective
”的自定义对象,该对象还实现了
可序列化的
。我有一个静态实用程序类,它序列化并读取我的模型。这段代码已经用一个“
ImageModel
”在main方法中进行了测试,一切都很正常

但当我试图在实际程序中使用它时,我遇到了一个问题。“
ImageModel
”类在我的系统类中声明,名为“
MainWindow
”,它扩展了
JFrame
,是大多数不同类之间的链接。由于某些原因,我无法执行类似于
MainWindow.getModel()
的操作来序列化模型。编译器认为我的“
EventFactory
”不可序列化。这个类也在“
MainWindow
”中声明,但我甚至不理解Java为什么要序列化它,我的印象是Java不仅要序列化模型,还要序列化GUI

以下是代码段:

我的模型:

public class ImageModel extends Observable implements Cloneable, Serializable {

private String path;
private ArrayList<Observer> observers;
private ArrayList<Perspective> perspectives;
private int numPerspectives;
private Perspective selectedPerspective;
...
}
声明模型和其他元素的实际GUI:

public class MainWindow extends JFrame {

    private final int GRID_ROWS = 0;
    private final int GRID_COLUMNS = 2;
    private final int NUM_PERSPECTIVE = 3;
    private JPanel mainPane;
    private ArrayList<View>  perspectiveList;
    private ImageModel imageModel;
    private EventFactory eventFactory;
    private JMenu menu;
    private JToolBar toolBar;
 ...
 }
以下是我的两个实用函数,以备您需要:

public static void serializeModel(ImageModel imageModel)
{
    String filename = "TEST.ser";

    FileOutputStream fos = null;
    ObjectOutputStream out = null;

    try
    {
        fos = new FileOutputStream(filename);
        out = new ObjectOutputStream(fos);
        out.writeObject(imageModel);
        out.close();
    }
    catch (IOException ex) 
    {
        ex.printStackTrace();
    }

}

public static ImageModel restoreModel(String filename)
{
    ImageModel imageModel = null;
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try
    {
        fis = new FileInputStream(filename);
        in = new ObjectInputStream(fis);
        imageModel = (ImageModel)in.readObject();
        in.close();
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }
    catch(ClassNotFoundException ex)
    {
        ex.printStackTrace();
    }

    return imageModel;
}
下面是我在处理实际用例时收到的错误的堆栈跟踪:


是的,就像我说的,就像Java试图序列化模型周围的其他东西一样。

我猜
EventFactory
以某种方式进入了
ImageModel
的字段。可能与
观察者
间接链接。也许您应该在尝试序列化或将该字段设置为“瞬态”字段之前清除该列表。我猜,
EventFactory
正在某种程度上进入
ImageModel
的字段。可能与
观察者
间接链接。在尝试序列化或将该字段设置为
transient

之前,您可能应该清除该列表。这不是一个真正的答案,但如果您想解决这个问题,请将EventFactory更改为transient data成员。例如:“私人瞬态事件工厂事件工厂”;1)为了更快地获得更好的帮助,请发布一个。2) 将堆栈跟踪的至少前50行直接放入问题中。大多数人不会关注某个链接。这不是一个真正的答案,但如果你想解决它:将EventFactory更改为临时数据成员。例如:“私人瞬态事件工厂事件工厂”;1)为了更快地获得更好的帮助,请发布一个。2) 将堆栈跟踪的至少前50行直接放入问题中。大多数人不会关注链接。也许问题应该是“MainWindow是ImageModel的观察者吗?”好的,首先,MainWindow不是观察者,我在其他地方有实现观察者的视图。但是,@Steven,我刚刚完全知道你提到的!实际问题存在于ImageModel中。它包含一个观测者数组,这些观测者是包含对MainWindow的引用的视图!所以它确实在尝试序列化整个类!好的,谢谢大家。也许问题应该是“MainWindow是ImageModel的观察者吗?”好的,首先,MainWindow不是观察者,我在其他地方有实现观察者的视图。但是,@Steven,我刚刚完全知道你提到的!实际问题存在于ImageModel中。它包含一个观测者数组,这些观测者是包含对MainWindow的引用的视图!所以它确实在尝试序列化整个类!好的,谢谢你们。
    MainWindow mw = new MainWindow();

    /*
     * Does NOT work:
     * ImageModel imageModel= mw.getImageModel();
     * Utility.serializeModel(imageModel); //Crashes
     * 
     * Works:
     * 
     * ImageModel imageModel= new ImageModel();
     * Utility.serializeModel(imageModel);
     * 
     */
public static void serializeModel(ImageModel imageModel)
{
    String filename = "TEST.ser";

    FileOutputStream fos = null;
    ObjectOutputStream out = null;

    try
    {
        fos = new FileOutputStream(filename);
        out = new ObjectOutputStream(fos);
        out.writeObject(imageModel);
        out.close();
    }
    catch (IOException ex) 
    {
        ex.printStackTrace();
    }

}

public static ImageModel restoreModel(String filename)
{
    ImageModel imageModel = null;
    FileInputStream fis = null;
    ObjectInputStream in = null;
    try
    {
        fis = new FileInputStream(filename);
        in = new ObjectInputStream(fis);
        imageModel = (ImageModel)in.readObject();
        in.close();
    }
    catch(IOException ex)
    {
        ex.printStackTrace();
    }
    catch(ClassNotFoundException ex)
    {
        ex.printStackTrace();
    }

    return imageModel;
}