从文件中读取会导致serialVersionUID错误

时间:2013-06-19 15:53:26

标签: java serialization

我一直在寻找互联网(包括stackoverflow)来解释我遇到的这个错误,但是没有得到答案(或者至少有一个我能理解的答案)。

我正在尝试序列化一个类,以便将对象保存到文件中。第一步是读取文件的当前内容,以便我可以添加一个新对象。为此,我使用此代码:

//masterFilePath is a java.io.File that contains the "master file" I'm reading.
//ReportList is a simple extension of ArrayList

String[][] returner = null; 
ReportList listOfReports = null;

try{
    FileInputStream fileReader = new FileInputStream(masterFilePath);
    ObjectInputStream objectReader = new ObjectInputStream(fileReader);
    listOfReports = (ReportList) (objectReader.readObject()); //Problem Line
    objectReader.close();

} catch (IOException | ClassNotFoundException e){
    e.printStackTrace();
}

当它到达标记为//Problem Line的行时,会抛出此错误:

com.Private.automatorContainers.ReportList; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 8996775622132817386

我知道8996...serialVersionUID我目前在ReportList Serializable我不知道的是1来自哪里。

我的工作理论是这样的:在我在ReportList中实现1L之前,我有一个等于serialVersionUID的UID,所以我假设1来自哪里(对吗?请确认或拒绝?)< / p>

我有两个问题。首先,UID存储在哪里?我不知道那些存储在.java文件之外的东西?我认为其他一切都是在编译时完成的。显然,我的理解存在漏洞。

其次,如何让我的程序意识到1是错误的{{1}}并且需要更新?

2 个答案:

答案 0 :(得分:2)

这里的根本问题是文件系统上该文件的内容是使用ReportList版本编写的,该版本与正在运行的代码使用的版本不兼容。 Java在将数据写入流时记录对象类的serialVersionUID,从而检测到这种不兼容性。稍后,当您从流中读回该对象时,Java会将记录的serialVersionUID与它在运行时为对象类发现的serialVersionUID进行比较。

您可以选择:

  • 使用最新版本的正在运行的代码重新创建该内容,使用您最初用于生成它的任何过程。
  • 修改正在运行的代码,使其与最初编写文件的版本兼容,方法是将正在运行的代码中serialVersionUID类的ReportList设置为1L以匹配其中的内容该文件,正如此主题中的其他人所建议的那样。请注意,只有在确定时,才能执行此操作文件中对象中的字段与最新代码中的字段相同,或者您已覆盖默认对象序列化行为。

答案 1 :(得分:0)

如果流声明序列化对象具有serialVersionUID = 1,则读取它的唯一方法是将类serialVersionUID也设置为1.

private static final long serialVersionUID = 1L;

如果你没有定义serialVersionUID java将根据你的类的属性为你生成一个,这很可能不是1。

当您将对象写入文件时,似乎serialVersionUid在类定义中为1。

将定义更改为1,重新编译JAR,它应该起作用。