0

我有一个这种形式的类:

public class Foo implements Serializable {

    private static final long serialVersionUID = 20130605L;

    private Object fields[];

    // Methods, etc.
}

有一段时间这没问题,但现在(为了可读性和维护)已转换为:

public class Foo implements Serializable {

    private static final long serialVersionUID = 20130605L;

    private String field1;
    private String field2;
    private Boolean fiedl3;

    // Methods, etc.
}

当您使用新类版本读取旧文件时,问题就来了。如果您使用不同的serialVersionUID,则不兼容。如果您使用相同的 serialVersionUID,我需要实现一些东西以使其兼容。这是我的方法,覆盖private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException所以我可以手动检查文件中的对象是什么版本。

问题再次出现在我想使用的java.io.ObjectInputStream.defaultReadObject();地方,因此它会自动为下一个版本执行“魔法”(在女巫中,新字段将是可选的)。所以我有类似的东西:

public class Foo implements Serializable {

    private static final long serialVersionUID = 20130605L;

    private String field1;
    private String field2;
    private Boolean fiedl3;

    // Methods, etc.

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {


        Object obj = in.readObject();

            if (obj instanceof Object[]) {
            Object[] tmp = (Object[])obj;
            field1 = (String)obj[0];
            field2 = (String)obj[1];
            // ....
        } else {
            in.defaultReadObject();
        }
    }
}

问题是,由于我已经读取了流的一部分,defaultReadObject 方法崩溃了。

我已经搜索了一个可以让你读取一个对象两次的 Stream,但我没有找到它。我也知道我可以完全手动进行读取,但是每次添加另一个字段时,我都需要修改它(在 中defaultReadObject,当它写入字段名称时,它只能恢复自动读取的字段)。

所以我的问题是¿我怎样才能做到?

注意:我只需要兼容性是从新类对象中读取旧类对象和从新类对象中读取新类对象。我也读过其他问题,但他们只回答了如何规划一个好的班级来获得后卫兼容性(我应该在之前读过它:-()。

4

1 回答 1

1

我找到的唯一解决方案是保持对旧字段的引用。注意可以设置为transient因为这样就不会被读取了,所以必须永远携带。

public class Foo implements Serializable {

    private static final long serialVersionUID = 20130605L;

    private Object fields[]; // So we can read it in old saved version.

    private String field1;
    private String field2;
    private Boolean fiedl3;

    // Methods, etc.

    private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {


        in.defaultReadObject();


        if (fields != null) {
            // If we have read an old version.
            field1 = (String)fields[0];
            field2 = (String)fields[1];
            field3 = (Boolean)fields[2];
            // ....

            // We set fields to null so no more space is waste than necessary.
            fields = null;
        }

    }
}
于 2013-07-24T09:44:06.640 回答