Serializable和Parcelable接口可以完成对象的序列化过程。
当我们需要通过Intent和Binder传输数据时就需要使用Parcelable或者Serializable;当我们需要把对象持久化到存储设备上或者通过网络传输给其它客户端时也需要使用Serializable。
一、Serializable接口
Serializable是Java提供的一个序列号接口,它是一个空接口,为对象提供标准的序列化和反序列化操作。
//序列化对象
public class Person implements Serializable{ //实现Serializable接口
private static final long serialVersionUID = 7060210544600464481L; //声明serialVersionUID
private String name;
private int age;
public Person(String, name, int age) {
this.name = name;
this.age = age;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
public int getAge(){
return age;
}
public void setAge(int age){
this.age = age;
}
}
//序列化过程
Person person = new Person("Tomy", 28);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(person);
out.close();
//反序列化过程
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
Person person = (Person)in.readObject();
in.close();
serialVersionUID工作机制:
序列化的时候系统会把当前类的serialVersionUID写入序列化文件中(也可能是其他中介),当反序列化的时候系统会去检测文件中的serialVersionUID,看它是否和当前类的serialVersionUID一致,如果一致就说明序列化的类的版本和当前类的版本是相同的,这个时候可以成功反序列化,否则就说明当前类和序列化的类相比发生了某些变换,比如成员变量的数量、类型可能发生了改变,这个时候是无法正常反序列化的。
需要注意两点:
(1)静态成员变量属于类而不属于对象,所以不会参与序列化过程。
(2)用transient关键字标记的成员变量不参与序列化过程。
二、Parcelable接口
只要实现Parcelable接口,一个类的对象就可以实现序列化并通过Intent和Binder传递。系统提供了许多实现Parcelable接口的类,比如Intent、Bundle、Bitmap等,同时List和Map也可以序列化,前提是它们里面的每个元素都是可序列化的。
public class Person implements Parcelable {
private String name;
private int age;
pivate Book book; //另一个可序列化的对象
public int describeContents() {
return 0; //几乎所有情况都返回0,仅当当前对象中存在文件描述符时返回1
}
public void writeToParcel(Parcel out, int flags) { //序列化
out.writeString(name);
out.writeInt(age);
out.writeParcelable(book, 0);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
public Person createFromParcel(Parcel in) { //反序列化
return new Person(in); //创建序列化对象
}
public Person[] newArray(int size) {
return new Person[size]; //创建序列化数组
}
};
private Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
this.book = in.readParcelable(Thread.currentThread().getContextClassLoader()); //传递当前线程的上下文类加载器
}
}
三、总结
Serializable是Java中的序列化接口,其使用起来简单但是开销很大,序列化和反序列化过程需要大量I/O操作。而Parcelable是Android中的序列化方式,使用起来稍微麻烦但是效率高,这是Android推荐的序列化方式,因此首选Parcelable。
Parcelable主要用在内存序列化。
Serializable主要用在将对象序列化到存储设备或者将对象序列化后通过网络传输。