尝试保存和读取文件时获取java.io.InvalidClassException
这是将类设置保存到文件的代码尝试保存和读取文件时获取java.io.InvalidClassException,java,serialization,io,Java,Serialization,Io,这是将类设置保存到文件的代码 public static void save(Settings settings) { try { ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream(settingsFile)); os.writeObject(settings); os.c
public static void save(Settings settings) {
try {
ObjectOutputStream os =
new ObjectOutputStream(
new FileOutputStream(settingsFile));
os.writeObject(settings);
os.close();
} catch(Exception e) {
e.printStackTrace();
}
}
此代码将读取该文件并返回被强制转换为设置的对象
错误是get位于
public static Settings load() {
try {
ObjectInputStream is =
new ObjectInputStream(
new FileInputStream(settingsFile));
Settings settings = (Settings) is.readObject();
is.close();
return settings;
} catch(Exception e) {
e.printStackTrace();
}
return null;
}
而StackTrace是
Settings settings = (Settings) is.readObject();
我不完全清楚为什么会出现这个错误,因为写入文件的对象是设置,而正在读取的对象也是设置。任何帮助都将不胜感激您序列化的类的版本为
X
,当前使用的设置类的版本为Y
(其中versions是每个Serializable
拥有的版本UID,即使您没有定义一个,它也会通过查看类内部来由Java生成)
将来,在使可序列化的类中定义一个私有(不管它是否也是公共的/受保护的)静态最终长serialVersionUID
,并使用一个值(例如1L
)将避免此问题
要立即修复异常,请定义一个值为52156251621355973的serialVersionUID
(因此它们将匹配)并反序列化它(这是不安全的)
无论如何,我应该用新的UID值(1L?)重新序列化它,使其始终兼容,因为如果不提供此值,可能会鼓励其他人出错
JavaDoc比我解释得更好
序列化运行时与每个可序列化类关联
版本号,称为serialVersionUID,在
反序列化以验证序列化的发送方和接收方
对象已为该对象加载与兼容的类
关于序列化。如果接收器已为
对象的SerialVersionId与的SerialVersionId不同
对应发件人的类,则反序列化将导致
InvalidClassException。可序列化类可以声明自己的类
通过声明名为
“serialVersionUID”必须是静态的、最终的且类型为long:
java.io.InvalidClassException: com.Settings; local class incompatible: stream classdesc serialVersionUID = 5215625451621355973, local class serialVersionUID = -6263468811172060812
at java.io.ObjectStreamClass.initNonProxy(Unknown Source)
at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
at java.io.ObjectInputStream.readClassDesc(Unknown Source)
at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at com.Settings.load(Settings.java:51)
at com.Main.main(Main.java:23)
如果
serializable类未显式声明serialVersionUID,
然后序列化运行时将计算默认值
该类的SerialVersionId值基于
类,如Java(TM)对象序列化中所述
但是,强烈建议所有
可序列化类显式声明serialVersionUID值,因为
默认的serialVersionUID计算对类高度敏感
详细信息可能因编译器实现而异,可以
因此,在运行期间会导致意外的InvalidClassException
因此,为了保证一致的serialVersionUID
跨不同java编译器实现的值,可序列化
类必须声明显式的serialVersionUID值。它也是
强烈建议显式serialVersionUID声明使用
私有修饰符,因为此类声明仅适用于
立即声明的类--SerialVersionId字段不可用
用作继承成员。数组类不能声明显式
serialVersionUID,因此它们始终具有默认的计算值,但
对于以下情况,不需要匹配serialVersionUID值
数组类
检查代码中的serialVersionUID-它是可序列化类的通用版本标识符
e、 g.static final long serialVersionId=1L;
反序列化使用此数字来确保加载的类与序列化对象完全对应。如果找不到匹配项,则会引发InvalidClassException能否显示设置的定义
?自上次序列化对象以来,您是否更改了类定义?哇,我觉得很傻。我在Se中编辑了一些内容ttings类在我序列化它之后,对你来说,我认为这是把它搞砸了。我刚刚重新序列化了文件,它工作得很好。如果你把它作为一个答案,我会标记它已解决。谢谢你的帮助!我现在明白了。这是我第一次尝试使用Serializable。谢谢!没问题:)如果你的问题已解决,考虑接受我的回答(或者任何其他帮助你的答案)
ANY-ACCESS-MODIFIER static final long serialVersionUID = 42L;