我一直在寻找互联网(包括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}}并且需要更新?
答案 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,它应该起作用。