我创建了客户端和服务器,然后在客户端添加了一个用于序列化的类,然后只需将其转到硬盘驱动器中的客户端文件夹,然后将其分别粘贴到服务器相应的位置,分别为classname.class
和classname.java
。
它在我自己的笔记本电脑上运行良好,但是当我想在其他系统上继续工作时,当我打开项目文件夹并且客户端尝试连接到服务器后,出现以下错误:
Exception in thread "main" java.io.InvalidClassException: projectname.clasname; local class incompatible: stream classdesc serialVersionUID = -6009442170907349114, local class serialVersionUID = 6529685098267757690
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:562)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1582)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1495)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1731)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1328)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:350)
到底是怎么回事?是因为我使用旧版本的IDE运行该程序吗?
编辑
import java.io.Serializable;
import java.net.URL;
public class KeyAdr implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
public URL adr;
public String key;
}
最佳答案
如果一个类没有在代码中显式定义private static final long serialVersionUID
,它将自动生成,并且不能保证不同的机器将生成相同的id。看起来正是这样。
同样,如果类在任何方面都不同(使用不同版本的类),则自动生成的serialVersionUID
也将不同。
在Serializable
界面的docs中:
如果可序列化的类未显式声明serialVersionUID
,则序列化运行时将根据该类的各个方面为该类计算默认的serialVersionUID
值,如Java(TM)对象序列化规范中所述。但是,强烈建议所有可序列化的类显式声明serialVersionUID
值,因为默认的serialVersionUID
计算对类详细信息高度敏感,而类详细信息可能会根据编译器的实现而有所不同,因此可能在反序列化期间导致意外的InvalidClassExceptions
。因此,为了保证不同Java编译器实现中一致的serialVersionUID
值,可序列化的类必须声明一个显式的serialVersionUID
值。还强烈建议显式serialVersionUID
声明在可能的情况下使用private
修饰符,因为此类声明仅适用于立即声明的类-serialVersionUID
字段作为继承成员没有用。数组类不能声明显式的serialVersionUID
,因此它们始终具有默认的计算值,但对于数组类,无需匹配serialVersionUID
值。
您应该在类定义中定义serialVersionUID
,例如:
class MyClass implements Serializable {
private static final long serialVersionUID = 6529685098267757690L;
...
关于java - java.io.InvalidClassException:本地类不兼容:,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57767038/