java.io.InvalidClassException:本地类不兼容:

lon*_*ome 28 java serialization client-server deserialization

我创建客户端和服务器,然后在添加客户端类的序列化的目的,然后简单地刚走到客户在我的硬盘驱动器的文件夹,并将其粘贴到服务器correponding位置,都classname.classclassname.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)
Run Code Online (Sandbox Code Playgroud)

到底是怎么回事?是因为我使用较旧版本的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;
}
Run Code Online (Sandbox Code Playgroud)

tru*_*ity 44

如果一个类没有private static final long serialVersionUID在代码中明确定义它,它将被自动生成,并且不能保证不同的机器将生成相同的id; 看起来这正是发生的事情.此外,如果类以任何方式不同(使用不同版本的类),自动生成的serialVersionUIDs也将是不同的.

Serializable界面的文档:

如果可序列化类未显式声明a serialVersionUID,则序列化运行时将serialVersionUID基于类的各个方面计算该类的默认值,如Java(TM)对象序列化规范中所述.但是,强烈建议所有可序列化类显式声明serialVersionUID值,因为默认serialVersionUID计算对类详细信息高度敏感,可能因编译器实现而异,因此InvalidClassExceptions在反序列化期间可能会导致意外.因此,为了保证serialVersionUID跨不同java编译器实现的一致值,可序列化类必须声明一个显式serialVersionUID值.强烈建议显式serialVersionUID声明private尽可能使用修饰符,因为此类声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员无用.数组类不能声明为显式serialVersionUID,因此它们始终具有默认的计算值,但是serialVersionUID对于数组类,不需要匹配值.

您应该serialVersionUID在类定义中定义一个,例如:

class MyClass implements Serializable {
    private static final long serialVersionUID = 6529685098267757690L;
    ...
Run Code Online (Sandbox Code Playgroud)

  • 尝试清理项目输出(编译时生成的`.class`文件)并重建(重新编译)项目. (3认同)

bel*_*lka 6

可能发生的一件事:

  • 1:您使用给定的库 A(版本 X)创建序列化数据
  • 2:然后您尝试使用相同的库 A(但版本 Y)读取此数据

因此,在版本 X 的编译时,JVM 将生成第一个序列 ID(对于版本 X),并且它将对另一个版本 Y(另一个序列 ID)执行相同的操作。

当您的程序尝试对数据进行反序列化时,它无法反序列化,因为这两个类没有相同的 Serial ID,并且您的程序无法保证两个 Serialized 对象对应于相同的类格式。

假设您同时更改了构造函数,这对您来说应该是有意义的。