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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19806496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 20:20:24  来源:igfitidea点击:

Why am I getting java.io.NotSerializableException when the class implements Serializable interface?

javaserialization

提问by Suhail Gupta

As I try to serializean object with a call , stashCon.stash()I get java.io.NotSerializableExceptioneven when the class StashConimplements Serializableinterface.

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

What could be the reason for this ?

这可能是什么原因?

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;
}

Following method is of the class StashCon

以下方法属于该类 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();
    } 
}

Exception

例外

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.run(SignIn.java:214)
at java.lang.Thread.run(Thread.java:619)

回答by constantlearner

XMPPConnection is coupled to physical resources (TCP sockets) on the machine in which it resides, therefore it cannot be made serializable. It is also has an identitiy associated with the connection to the server which cannot be duplicated, since a full JID can only be connected to the same server once, a second connection would force the other one to get disconnected.

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

The connection should not be put into the session, you have to manage it outside of that scope.

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

回答by Matthias

Your object contains member variables which are themselves not serializable (an instance of org.jivesoftware.smack.XMPPConnection).

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

If you really want to serialize your object, you'll have to do something about that member variable. One option would be to declare that variable as transientso that it is not serialized.

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

On deserialization however, you'll have to handle that member (like reastablishing the connection). For this you could define the method readObjectwhich is called during deserialization. In there you can (and probably should) initialize all transient member variables to set your object to a good state.

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

Hereis also a good question discussing serialization.

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