当我尝试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)
答案 0 :(得分:7)
您的对象包含本身不可序列化的成员变量(org.jivesoftware.smack.XMPPConnection
的实例)。
如果你真的想序列化你的对象,你将不得不对该成员变量做些什么。一种选择是将该变量声明为transient
,以便它不被序列化。
然而,在反序列化时,您必须处理该成员(例如重新建立连接)。为此,您可以定义在反序列化期间调用的方法readObject
。在那里,您可以(并且可能应该)初始化所有瞬态成员变量,以将您的对象设置为良好状态。
Here也是一个讨论序列化的好问题。
答案 1 :(得分:5)
XMPPConnection与其所在机器上的物理资源(TCP套接字)耦合,因此无法进行序列化。它还具有与服务器连接相关联的标识,该连接无法复制,因为完整的JID只能连接到同一服务器一次,第二次连接会强制另一个连接断开。
不应将连接放入会话中,您必须在该范围之外进行管理。