英文:
Error when I try to deserialize an object
问题
我和我的朋友正在使用GitHub进行编码,在我们更新主类时,IDE提供了以下错误:
Exception in thread "main" java.io.InvalidClassException: Packages.contoCorrente; local class incompatible: stream classdesc serialVersionUID = -433050874178120905, local class serialVersionUID = -5213999116280532749
at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1958)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1827)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2115)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at java.base/java.util.ArrayList.readObject(ArrayList.java:928)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2271)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2142)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at ObjectWrite.main(ObjectWrite.java:31)
为了解决这个问题,我总是删除主对象文件,以便它可以重新构建。我还附上了处理反序列化的代码部分,希望有人能帮助我。
public static void main(String[] args) throws Exception {
ArrayList<contoCorrente> contiCorrentiArray;
File file = new File("contiCorrenti");
if (file.exists()) {
FileInputStream fileIn = new FileInputStream(file);
ObjectInputStream fileObjIn = new ObjectInputStream(fileIn);
//noinspection unchecked
contiCorrentiArray = (ArrayList<contoCorrente>) fileObjIn.readObject();
fileObjIn.close();
fileIn.close();
} else {
contiCorrentiArray = new ArrayList<>();
}
System.out.println("Numero Conti Presenti: " + contiCorrentiArray.size() + "\n");
}
英文:
I am coding using GitHub with my friend, and when we update the main class, the IDE provides us the following error:
Exception in thread "main" java.io.InvalidClassException: Packages.contoCorrente; local class incompatible: stream classdesc serialVersionUID = -433050874178120905, local class serialVersionUID = -5213999116280532749
at java.base/java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:689)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1958)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1827)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2115)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at java.base/java.util.ArrayList.readObject(ArrayList.java:928)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2271)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2142)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1646)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:464)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at ObjectWrite.main(ObjectWrite.java:31)
To fix the problem, I always delete the main object file, so it can rebuild it. I am also attaching the part of code that deals with deserialization, in the hope that someone will help me.
public static void main(String[] args) throws Exception {
ArrayList<contoCorrente> contiCorrentiArray;
File file = new File("contiCorrenti");
if (file.exists()) {
FileInputStream fileIn = new FileInputStream(file);
ObjectInputStream fileObjIn = new ObjectInputStream(fileIn);
//noinspection unchecked
contiCorrentiArray = (ArrayList<contoCorrente>) fileObjIn.readObject();
fileObjIn.close();
fileIn.close();
} else {
contiCorrentiArray = new ArrayList<>();
}
System.out.println("Numero Conti Presenti: " + contiCorrentiArray.size() + "\n");
答案1
得分: 1
你和你的伴侣是否拥有相同的 serialVersionUID?
如果不是的话,你们两个都应该定义它,以防止它被自动计算。
根据文档:
如果一个可序列化的类没有显式地声明serialVersionUID,那么序列化运行时将根据类的各个方面计算出一个默认的serialVersionUID值,如Java(TM)对象序列化规范中所述。然而,强烈建议所有可序列化的类都显式地声明serialVersionUID值,因为默认的serialVersionUID计算对编译器实现可能因类细节而异,因此在反序列化过程中可能会导致意外的InvalidClassExceptions。因此,为了保证在不同的Java编译器实现之间具有一致的serialVersionUID值,可序列化的类必须声明一个显式的serialVersionUID值。还强烈建议在可能的情况下,显式的serialVersionUID声明使用private修饰符,因为这样的声明仅适用于立即声明的类 - serialVersionUID字段作为继承成员是没有用的。数组类不能声明显式的serialVersionUID,因此它们始终具有默认计算值,但是对于数组类,匹配的serialVersionUID值的要求被放宽了。
英文:
Do you and your Partner have the same serialVersionUID?
If not, you both should define it, so it doesn't get calculated automatically.
From the docs:
> If a serializable class does not explicitly declare a
> serialVersionUID, then the serialization runtime will calculate a
> default serialVersionUID value for that class based on various aspects
> of the class, as described in the Java(TM) Object Serialization
> Specification. However, it is strongly recommended that all
> serializable classes explicitly declare serialVersionUID values, since
> the default serialVersionUID computation is highly sensitive to class
> details that may vary depending on compiler implementations, and can
> thus result in unexpected InvalidClassExceptions during
> deserialization. Therefore, to guarantee a consistent serialVersionUID
> value across different java compiler implementations, a serializable
> class must declare an explicit serialVersionUID value. It is also
> strongly advised that explicit serialVersionUID declarations use the
> private modifier where possible, since such declarations apply only to
> the immediately declaring class--serialVersionUID fields are not
> useful as inherited members. Array classes cannot declare an explicit
> serialVersionUID, so they always have the default computed value, but
> the requirement for matching serialVersionUID values is waived for
> array classes. `
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论