关于序列化,serialVersionUID和不兼容的类

wwy*_*wyt 9 java android

我在这里看到了一些相关的问题和答案,但它们似乎没有帮助.所以我想我需要在这里发一个单独的问题:

我有一个可序列化的类MyDataClass,它包含一些可序列化的内部类.我使用FileOutputStream和将其保存到文件中ObjectOutputStream.在阅读它时,我有时会得到一个例外(可能ClassNotFoundException或者InvalidClassException我不确定),并且异常的消息是这样的:

12-01 18:44:16.479: D/My App Name(534): ***** exception occurred 
com.xyz.myapp.lib.am; Incompatible class (SUID): com.xyz.myapp.lib.am: 
static final long serialVersionUID =3894560643019408205L; but expected 
com.xyz.myapp.lib.am: static final long serialVersionUID =-4215454881436014736L;
Run Code Online (Sandbox Code Playgroud)

MyDataClass 是这样的:

public static class MyDataClass implements Serializable {

    private static final long serialVersionUID = 0x98F22BF5;
    .....
    public boolean bNoTitle;
    public short syncOption;
    .....

    public class InnerClass implements Serializable {
        private static final long serialVersionUID = 0x99D32720;
        double premium;
        double interest;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我使用以下代码来阅读它:

MyDataClass oc;
FileInputStream fin = new FileInputStream(dataFile);
ObjectInputStream ois = new ObjectInputStream(fin);
oc = (MyDataClass)ois.readObject();
ois.close();
fin.close();
Run Code Online (Sandbox Code Playgroud)

readObject抛出异常,而不是每次都抛出异常,但有时候我无法查明到目前为止.我在某处读到,实际写入文件的serialVersionUID不是我在代码中指定的.因此,当它被回读时,UID不匹配,因此异常.是对的吗?如果是这样,我如何确保没有异常并且按预期读回对象?

谢谢.

编辑:似乎从Eclipse调试时,一切都很好.但是在我使用构建之后ant,问题就会出现.但不是每次都在ant构建之后,但有时候.

编辑:我在另一篇文章中看到:

你在读文件吗?在这种情况下,如果您现在添加serialVersionUID并不重要,它与文件中存储的不同,并且会创建异常.一个快速的解决方案是将serialVersionUID设置为4209360273818925922L,这似乎是当时在那个文件中保存那些对象时由java自动生成的serialVersionUID.

当用户使用该应用程序时,我的文件将被多次保存/读取.如果Java 每次保存文件时都会分配不同的UID ,那么我怎样才能预先在代码中接入一个数字?我需要一个真正的静态UID,即使在ant构建之后也不会改变.

Ash*_*Jha 1

当您显式声明serialVersionUID时,只要serialVersionUID未更改(并且类未发生大幅更改),序列化和反序列化就不会有问题。

从异常消息中,我觉得您可能有一些成员类也正在序列化,但没有显式串行版本 UID,因此您可能还需要在该类中显式声明serialVersionUID。

另一种可能性是,您可能不小心尝试读取在输入显式serialVersionUID 之前保存的文件。