Android Serializalbe对象序列化

时间:2023-01-02 22:56:56


Serializalbe接口

概述


Marks classes that can be serialized by ​​ObjectOutputStream​​ and deserialized by ​​ObjectInputStream​​.Warning: this interface limits how its implementing classes can change in the future. By implementing ​​Serializable​

作用: 让对象可以被 ObjectOutputStream 序列化,被 ObjectInputStream 反序列化。

警告: 这个接口限制了继承者在未来的变化。通过继承 Serializable 接口,将实例在内存中的分布作为二进制代码展现出来。如果修改继承了Serializable 接口类的私有变量的名字,是不安全的操作。

The Serialized Form

By default, the serialization mechanism encodes an object's class name, the names of its non-transient fields (including non-public fields), and the values of all of those fields. The output is an opaque sequence of bytes. Those bytes can be decoded into a new, equivalent instance as long as the decoder has compatible versions of the originating classes.

序列化的形式:

默认的,序列化机制对类名,类中非临时变量(包括不是 public 的 变量),以及所有这些变量的值。输出是一串不透明的字节序列。这些字节序列可以被反解码成一个新的,等效的实例。只要用和类中序列化版本号对应的解码。

Changing the class name, field names or field types breaks serialization compatibility and complicates interoperability between old and new versions of the serializable class. Adding or removing fields also complicates serialization between versions of a class because it requires your code to cope with missing fields.


改变类名,变量名和变量类型,会破坏类在新旧版本之间的兼容性和通用性。删除变量也会破坏通用性,因为需要代码去处理这些没有的变量。



Every serializable class is assigned a version identifier called a ​​serialVersionUID​​. By default, this identifier is computed by hashing the class declaration and its members. This identifier is included in the serialized form so that version conflicts can be detected during deserialization. If the local ​​serialVersionUID​​ differs from the ​​serialVersionUID​​ in the serialized data, deserialization will fail with an ​​InvalidClassException​​.


每一个序列化的类都绑定一个叫 serivalVersionUID 的版本标识。默认情况下,这个标识是通过对类的及其成员的声明进行哈希计算出来的。这个标识号会被添加到序列化对象总,这样在反序列化的时候,如果 反序列化的id和对象本身的id不一样,可以被探测出来,并导致失败,同时返回 InvalidClassException.



You can avoid this failure by declaring an explicit ​​serialVersionUID​​. Declaring an explicit ​​serialVersionUID​​ tells the serialization mechanism that the class is forward and backward compatible with all versions that share that ​​serialVersionUID​​. Declaring a ​​serialVersionUID​

private static final long serialVersionUID = 0L;


If you declare a  ​​serialVersionUID​

, you should increment it each time your class changes incompatibly with the previous version. Typically this is when you add, change or remove a non-transient field.

You can take control of your serialized form by implementing these two methods with these exact signatures in your serializable classes:



private void writeObject(java.io.ObjectOutputStream out)
throws IOException {
// write 'this' to 'out'...



如果你声明了一个 serialVersionUID, 你应该在 你的类和之前版本不一样的时候对 serialVersionUID进行自加。通常,你应该在增加,改变,或者删除一个不是临时变量的成员。
你可以通过实现下面两个方法来控制你的序列化形式。
private void writeObject(java.io.ObjectOutputStream out)
private void readObject(java.io.ObjectInputStream in)


It is impossible to maintain serialization compatibility across a class name change. For this reason, implementing Serializable in anonymous inner classes is highly discouraged: simply reordering the members in the file could change the generated class name and break serialization compatibility. 
You can exclude member fields from serialization by giving them the transient modifier. Upon deserialization, the transient field's value will be null, 0, or false according to its type.


因为通过类名来获取 序列化的兼容性是不可能的,所以继承用匿名内部类来实现 Serializable 接口是很不鼓励的。简单的记录类里面的成员可能会导致类名改变。并破坏序列化的兼容性。

你可以通过给成员变量赋予临时属性的办法来删除他们,当反序列化的时候临时变量会根据它的类型取null 0,或者false等。



Implement Serializable Judiciously
Refer to Effective Java's chapter on serialization for thorough coverage of the serialization API. The book explains how to use this interface without harming your application's maintainability.

谨慎的使用 Serializalbe 接口。




可以参考 Effective java 中有关 serialzation API 的有关章节。这本书讲述了如何使用怎样在不破坏程序可维护性的情况下使用序列化。






Recommended Alternatives

JSON is concise, human-readable and efficient. Android includes both a

​streaming API​​ and a

​tree API​​ to read and write JSON. Use a binding library like

​​​GSON​​ to read and write Java objects directly.




推荐的其他选择



JSON 是很精简,易读和高效的。Android 中包括了对其进行流操作的API 和 节点操作的API,来读写JSON,可以用向GSON 这样一个库来直接读写 java 对象