Java试图序列化不存在的东西?

时间:2014-07-13 22:43:17

标签: java swing serialization jcombobox

我创建了一个用于保存comboxbox内容并加载它们的类。我使用ObjectOutput并直接保存模型。问题是,我得到一个例外:

java.io.WriteAbortedException: writing aborted; java.io.NotSerializableException: javax.swing.SpringLayout

我真的不明白为什么会发生这种情况,因为我在任何代码中都没有使用SpringLayout(我可以告诉)。我甚至在stream.writeOutput(getModel());上设置了断点,getModel()肯定会返回DefaultComboboxModel,所以再次没有提到Spring布局。

然后我编译了我从(here)获得示例的代码,它工作正常。为什么会这样?

class MemComboBox extends JComboBox
{
    public static final int MAX_MEM_LEN = 30;

    public MemComboBox()
    {
        super();
        setEditable(true);
    }

    public void add(String item)
    {
        removeItem(item);
        insertItemAt(item, 0);
        setSelectedItem(item);
        if (getItemCount() > MAX_MEM_LEN)
            removeItemAt(getItemCount() - 1);
    }

    public void load(String fName)
    {
        try
        {
            if (getItemCount() > 0)
                removeAllItems();
            File f = new File(fName);
            if (!f.exists())
                return;
            FileInputStream fStream = new FileInputStream(f);
            ObjectInput stream = new ObjectInputStream(fStream);

            Object obj = stream.readObject();
            if (obj instanceof ComboBoxModel)
                setModel((ComboBoxModel) obj);

            stream.close();
            fStream.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void save(String fName)
    {
        try
        {
            FileOutputStream fStream = new FileOutputStream(fName);
            ObjectOutput stream = new ObjectOutputStream(fStream);
            Object object = getModel();
            stream.writeObject(object);

            stream.flush();
            stream.close();
            fStream.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

我在这里创建实例:

    languageList = new MemComboBox();
    languageList.setBounds(146, 167, 166, 22);
    languageList.load(ClientInfo.GetAppData() + "/languages.xml");
    languageList.addActionListener(comboboxAdded);
    getContentPane().add(languageList);

这是堆栈跟踪:

java.io.NotSerializableException: javax.swing.SpringLayout
    at java.io.ObjectOutputStream.writeObject0(Unknown Source)
    at java.io.ObjectOutputStream.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.writeObject(Unknown Source)
    at sun.reflect.GeneratedMethodAccessor14.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.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.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.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.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.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.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.access$300(Unknown Source)
    at java.io.ObjectOutputStream$PutFieldImpl.writeFields(Unknown Source)
    at java.io.ObjectOutputStream.writeFields(Unknown Source)
    at java.awt.Container.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 javax.swing.event.EventListenerList.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 org.CCInc.Psyc.Windows.NewClient$MemComboBox.save(NewClient.java:688)
    at org.CCInc.Psyc.Windows.NewClient$7.windowClosing(NewClient.java:540)
    at java.awt.AWTEventMulticaster.windowClosing(Unknown Source)
    at java.awt.Window.processWindowEvent(Unknown Source)
    at javax.swing.JDialog.processWindowEvent(Unknown Source)
    at java.awt.Window.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(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)

2 个答案:

答案 0 :(得分:5)

没有更多代码我无法确定,但是......

堆栈跟踪中的行at org.CCInc.Psyc.Windows.NewClient$MemComboBox.save(NewClient.java:688)表示MemComboBox类是NewClient类的内部类。如果它不是静态内部类,则序列化将尝试写出整个“NewClient”对象。这是因为在每个非静态内部类中都有对外部类的引用。

答案 1 :(得分:1)

查看堆栈跟踪。它无法序列化一个监听器。猜测听众是一个外部类,可能是MyComboBox本身。重做它,以便监听器是一个独立的类,可序列化,并且没有对Swing类的非瞬态引用。或者在序列化之前删除侦听器并在之后恢复它们。当你想到它时,反序列化的听众无论如何都无法做任何有用的事情。