查询Java序列化

ove*_*nge 2 java jnlp serialization deserialization

在现有的新成员方法中添加新成员方法之后,我面临以下问题class Response implements Serializable{}.没有声明显式的串行版本ID.多次尝试,我得到相同的序列号.

Error communicating with the webserver: com.abc.xyz.app.util.common.Response;
local class incompatible: stream classdesc serialversionUID = 
-3900355805473150430, local class serialversionUID = 
-6706527232726476603
Run Code Online (Sandbox Code Playgroud)

经过一些文档后,我尝试修改class Response附加行:private final static long serialVersionUID = 1L;.

通过此更改,以下是错误:

Error communicating with the webserver: com.abc.xyz.app.util.common.Response;
local class incompatible: stream classdesc serialversionUID = 
-3900355805473150430, local class serialversionUID = 1
Run Code Online (Sandbox Code Playgroud)

这些是位于webappstomcat文件夹中并xyz.jnlp在客户端计算机上加载的类.xyz.jnlp从远程网络服务器加载新客户机.但事情不起作用!

请帮我理解这个问题.

JB *_*zet 7

序列化对象时,类的串行版本UID将写入流.如果类没有,则使用确定性算法自动生成.

反序列化给定类的对象时,将本地类(硬编码或生成的)的串行版本UID与流中的串行版本UID进行比较.如果它们不匹配,则会出现异常:这意味着类不兼容.

因此,要解决您的问题,您有两个选择:

  1. 确保服务器和客户端始终共享同一个类.这是最好,最简单的解决方案.但它要求每次更新服务器时都更新所有客户端.
  2. 确保类始终兼容.由于您的旧类没有硬编码的serialVersionUID,并且您想要更改类并使其保持兼容,因此您需要使用与为初始版本自动生成的值相同的值对serialVersionUID进行硬编码.班级.当然,你必须要知道,如果添加字段,接收器将无法读取它们,并且如果删除字段,接收者对这些字段的值将为null,这可能会破坏不变量.

除非您完全理解更改的含义,这很难并且需要阅读序列化规范,否则我的建议是使用选项1:使客户端和服务器保持最新状态.

  • 尽管我们使用的是在客户端和服务器上没有显式串行版本ID的相同类,但是由于可能存在不同的算法,客户端和服务器上安装的不同版本的jvm可能会生成不同的序列ID.在我的情况下,他们生成相同的ID.因此,为了避免安装不同版本的jvm的问题,我们可以显式提供序列ID. (2认同)