当类实现Serializable接口时,为什么会得到java.io.NotSerializableException?

时间:2013-11-06 07:39:58

标签: java serialization

当我尝试serialize一个带有调用的对象stashCon.stash()时,即使类java.io.NotSerializableException实现StashCon接口,我也会得到Serializable

这可能是什么原因?

public boolean connect(String username,String password) {
    try {
        Openfire.connection.connect();
        Openfire.connection.login(username,password);
        stashCon = new StashCon(Openfire.connection);
        stashCon.stash(); // CALL THAT ATTEMPTS TO SERIALIZE THE OBJECT
    }catch(Exception exc){
        exc.printStackTrace();
        return false;
    }
    return true;
}

以下方法属于班级StashCon

public void stash() {
    try {
        FileOutputStream outputStream = new FileOutputStream(new File(Constants.BLAB_CONNECTION_FILE));
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);
        objectOutputStream.writeObject(this); // LINE 33
        objectOutputStream.close();
        outputStream.close();
    }catch(Exception exc) {
        exc.printStackTrace();
    } 
}

异常

java.io.NotSerializableException: org.jivesoftware.smack.XMPPConnection
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
at blab.StashCon.stash(StashCon.java:33)
at blab.Openfire.connect(Openfire.java:27)
at blab.ext.gui.SignIn$4.run(SignIn.java:214)
at java.lang.Thread.run(Thread.java:619)

2 个答案:

答案 0 :(得分:7)

您的对象包含本身不可序列化的成员变量(org.jivesoftware.smack.XMPPConnection的实例)。

如果你真的想序列化你的对象,你将不得不对该成员变量做些什么。一种选择是将该变量声明为transient,以便它不被序列化。

然而,在反序列化时,您必须处理该成员(例如重新建立连接)。为此,您可以定义在反序列化期间调用的方法readObject。在那里,您可以(并且可能应该)初始化所有瞬态成员变量,以将您的对象设置为良好状态。

Here也是一个讨论序列化的好问题。

答案 1 :(得分:5)

XMPPConnection与其所在机器上的物理资源(TCP套接字)耦合,因此无法进行序列化。它还具有与服务器连接相关联的标识,该连接无法复制,因为完整的JID只能连接到同一服务器一次,第二次连接会强制另一个连接断开。

不应将连接放入会话中,您必须在该范围之外进行管理。