5

当我尝试serialize调用一个对象时,即使类实现了接口,stashCon.stash()我也会得到。java.io.NotSerializableExceptionStashConSerializable

这可能是什么原因?

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)
4

2 回答 2

7

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

如果你真的想序列化你的对象,你必须对那个成员变量做一些事情。一种选择是声明该变量transient,使其不被序列化。

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

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

于 2013-11-06T07:52:23.270 回答
5

XMPPConnection 与它所在机器上的物理资源(TCP 套接字)耦合,因此它不能被序列化。它还具有与无法复制的服务器连接相关联的身份,因为完整的 JID 只能连接到同一服务器一次,第二个连接将迫使另一个连接断开连接。

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

于 2013-11-06T07:44:00.143 回答