ObjectOutputStream/Input在JAVA中可序列化

sta*_*oun 2 java serializable

我正在使用ObjectOutputStream将我的对象保存到.dat文件.我的问题是,如果我改变我的对象的源代码(例如我添加一个方法(getter))输入流无法加载数据并告诉我一个错误Serializable:有可能解决这个问题吗?.dat如果我更改源代码,我必须每次都生成新文件.

使用此方法:( 不要看对象类型 - 返回值)保存

public void saveToFile(HeaderOfMapTeachStructure hm, String nameOfFile) {
    try (ObjectOutputStream os = new ObjectOutputStream(
            new FileOutputStream(nameOfFile + "." + this.TYPE_OF_FILE))) {
        os.writeObject(hm);
    } catch (IOException e) {
        System.out.println("Error: " + e);
    }
}
Run Code Online (Sandbox Code Playgroud)

加载

public MapStandard loadFromFileMS(String nameOfFile) {
    MapStandard hm = null;
    InputStream inputStreaminputStream
            = getClass().getClassLoader().
            getResourceAsStream("data/" + nameOfFile + ".data");
    try {
        try (ObjectInputStream is = new ObjectInputStream(inputStreaminputStream)) {
            hm = (MapStandard) is.readObject();
        }
    } catch (IOException | ClassNotFoundException e) {
        System.out.println("Error: " + e);
    }
    return hm;
}
Run Code Online (Sandbox Code Playgroud)

错误是:

Error: java.io.InvalidClassException: MapVerb.RealVerb; local class incompatible: stream classdesc serialVersionUID = -887510662644221872, local class serialVersionUID = 7992494764692933500
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

有可能解决这个问题吗?

是.序列化中断的原因是生成的版本号更改.如果明确指定,则不会生成它,并且您将控制版本控制.这意味着您需要小心 - 如果您更改对象中的字段或这些字段的含义,您需要记住自己更改版本号.

您可以像这样指定序列化版本:

// It doesn't have to be constant, but that's fairly common.
private static final long serialVersionUID = ...; // Some constant
Run Code Online (Sandbox Code Playgroud)

有关Serializable更多信息,请参阅文档.

您可能还想考虑使用替代方法来存储数据 - Java中的默认二进制序列化相当脆弱.有许多替代方案 - 基于文本的格式,如XML,JSON或YAML,或二进制格式,如Protocol Buffers或Thrift.