Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java/Android中维护可序列化类_Java_Android_Serialization - Fatal编程技术网

在Java/Android中维护可序列化类

在Java/Android中维护可序列化类,java,android,serialization,Java,Android,Serialization,我将对象序列化为SQLiteOpenHelper中的blob,如下所示: final ByteArrayOutputStream bos = new ByteArrayOutputStream(); final ObjectOutputStream out = new ObjectOutputStream(bos); out.writeObject(value); out.close(); 每个类定义自己的serialVersionUID,该ID永远不会更改 序列化/反序列化实际上是如何工作的

我将对象序列化为SQLiteOpenHelper中的blob,如下所示:

final ByteArrayOutputStream bos = new ByteArrayOutputStream();
final ObjectOutputStream out = new ObjectOutputStream(bos);
out.writeObject(value);
out.close();
每个类定义自己的serialVersionUID,该ID永远不会更改

序列化/反序列化实际上是如何工作的?它是否记得字段的名称以及与之关联的值?如果我继续添加/删除字段,是否有可能修改现有字段的值

例如,假设我序列化了这个类:

public class Foo implements Serializable {
     private static final long serialVersionUID = 4068188167994381987L;
     String x;
     int y;
}

Where x is "A", and y is 1;
然后我修改类,如下所示:

public class Foo implements Serializable {
     private static final long serialVersionUID = 4068188167994381987L;
     float f;
     String x;
}

如果我继续添加/删除字段,那么每次我反序列化
Foo
x时是否仍然是“A”?

您不能删除字段。有关
可序列化
类的兼容更改,请参阅

是在类
Foo
更改后,对较旧的
Foo
进行反序列化会将x设置为“a”,但由于删除了一个字段,因此这不起作用

我建议保留旧字段
y
,并将其标记为
@已弃用

public class Foo implements Serializable {
    private static final long serialVersionUID = 4068188167994381987L;
    String x;
    float f;
    @deprecated int y;
}

不能删除字段。有关
可序列化
类的兼容更改,请参阅

是在类
Foo
更改后,对较旧的
Foo
进行反序列化会将x设置为“a”,但由于删除了一个字段,因此这不起作用

我建议保留旧字段
y
,并将其标记为
@已弃用

public class Foo implements Serializable {
    private static final long serialVersionUID = 4068188167994381987L;
    String x;
    float f;
    @deprecated int y;
}

否,如果更改字段顺序或字段类型,反序列化将无法正常工作。它将导致异常或读取不正确的数据

这就是为什么建议每次进行更改时都更改serialVersionUID,以便类的序列化格式发生更改


如果希望在不破坏序列化的情况下灵活地更改类内部结构,则应使用Externalizable接口。

否,如果更改字段顺序或字段类型,则反序列化将无法正常工作。它将导致异常或读取不正确的数据

这就是为什么建议每次进行更改时都更改serialVersionUID,以便类的序列化格式发生更改

如果希望在不破坏序列化的情况下灵活地更改类内部结构,则应使用Externalizable接口。

我将使用“神奇”序列化方法writeObject和readObject来定义自定义序列化流。这样,类的新版本就可以读取旧格式,并根据一些转换算法填充新字段(这里,读取y int并基于它设置f的值)

有关序列化“魔术”方法的详细信息,请参见此处:

我将使用“魔术”序列化方法writeObject和readObject来定义自定义序列化流。这样,类的新版本就可以读取旧格式,并根据一些转换算法填充新字段(这里,读取y int并基于它设置f的值)

有关序列化“魔术”方法的详细信息,请参见此处: