Serializable和Parcelable接口可以完成對(duì)象的序列化過(guò)程拖刃。
當(dāng)我們需要通過(guò)Intent和Binder傳輸數(shù)據(jù)時(shí)就需要使用Parcelable或者Serializable抖誉;當(dāng)我們需要把對(duì)象持久化到存儲(chǔ)設(shè)備上或者通過(guò)網(wǎng)絡(luò)傳輸給其它客戶(hù)端時(shí)也需要使用Serializable缠黍。
一怯屉、Serializable接口
Serializable是Java提供的一個(gè)序列號(hào)接口窥淆,它是一個(gè)空接口驰怎,為對(duì)象提供標(biāo)準(zhǔn)的序列化和反序列化操作钞馁。
//序列化對(duì)象
public class Person implements Serializable{ //實(shí)現(xiàn)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;
}
}
//序列化過(guò)程
Person person = new Person("Tomy", 28);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("cache.txt"));
out.writeObject(person);
out.close();
//反序列化過(guò)程
ObjectInputStream in = new ObjectInputStream(new FileInputStream("cache.txt"));
Person person = (Person)in.readObject();
in.close();
serialVersionUID工作機(jī)制:
序列化的時(shí)候系統(tǒng)會(huì)把當(dāng)前類(lèi)的serialVersionUID寫(xiě)入序列化文件中(也可能是其他中介)虑省,當(dāng)反序列化的時(shí)候系統(tǒng)會(huì)去檢測(cè)文件中的serialVersionUID,看它是否和當(dāng)前類(lèi)的serialVersionUID一致僧凰,如果一致就說(shuō)明序列化的類(lèi)的版本和當(dāng)前類(lèi)的版本是相同的探颈,這個(gè)時(shí)候可以成功反序列化,否則就說(shuō)明當(dāng)前類(lèi)和序列化的類(lèi)相比發(fā)生了某些變換训措,比如成員變量的數(shù)量伪节、類(lèi)型可能發(fā)生了改變光羞,這個(gè)時(shí)候是無(wú)法正常反序列化的。
需要注意兩點(diǎn):
(1)靜態(tài)成員變量屬于類(lèi)而不屬于對(duì)象架馋,所以不會(huì)參與序列化過(guò)程狞山。
(2)用transient關(guān)鍵字標(biāo)記的成員變量不參與序列化過(guò)程。
二叉寂、Parcelable接口
只要實(shí)現(xiàn)Parcelable接口萍启,一個(gè)類(lèi)的對(duì)象就可以實(shí)現(xiàn)序列化并通過(guò)Intent和Binder傳遞。系統(tǒng)提供了許多實(shí)現(xiàn)Parcelable接口的類(lèi)屏鳍,比如Intent勘纯、Bundle、Bitmap等钓瞭,同時(shí)List和Map也可以序列化驳遵,前提是它們里面的每個(gè)元素都是可序列化的。
public class Person implements Parcelable {
private String name;
private int age;
pivate Book book; //另一個(gè)可序列化的對(duì)象
public int describeContents() {
return 0; //幾乎所有情況都返回0山涡,僅當(dāng)當(dāng)前對(duì)象中存在文件描述符時(shí)返回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); //創(chuàng)建序列化對(duì)象
}
public Person[] newArray(int size) {
return new Person[size]; //創(chuàng)建序列化數(shù)組
}
};
private Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
this.book = in.readParcelable(Thread.currentThread().getContextClassLoader()); //傳遞當(dāng)前線程的上下文類(lèi)加載器
}
}
三堤结、總結(jié)
Serializable是Java中的序列化接口,其使用起來(lái)簡(jiǎn)單但是開(kāi)銷(xiāo)很大鸭丛,序列化和反序列化過(guò)程需要大量I/O操作竞穷。而Parcelable是Android中的序列化方式,使用起來(lái)稍微麻煩但是效率高鳞溉,這是Android推薦的序列化方式瘾带,因此首選Parcelable。
Parcelable主要用在內(nèi)存序列化熟菲。
Serializable主要用在將對(duì)象序列化到存儲(chǔ)設(shè)備或者將對(duì)象序列化后通過(guò)網(wǎng)絡(luò)傳輸看政。