1. Serializable和Parcelable的定義
1.1 Serializable
package java.io;
public interface Serializable {
}
實作示例:
public class Person implements Serializable{
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
}
1.2 Parcelable
public interface Parcelable
{
//内容描述接口,基本不用管
public int describeContents();
//寫入接口函數,打包
public void writeToParcel(Parcel dest, int flags);
//讀取接口,目的是要從Parcel中構造一個實作了Parcelable的類的執行個體處理。因為實作類在這裡還是不可知的,是以需要用到模闆的方式,繼承類名通過模闆參數傳入
//為了能夠實作模闆參數的傳入,這裡定義Creator嵌入接口,内含兩個接口函數分别傳回單個和多個繼承類執行個體
public interface Creator<T>
{
public T createFromParcel(Parcel source);
public T[] newArray(int size);
}
}
實作示例:
public class Person implements Parcelable{
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
//這裡的讀的順序必須與writeToParcel(Parcel dest, int flags)方法中寫的順序一緻
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
//這裡的讀的順序必須與writeToParcel(Parcel dest, int flags)方法中寫的順序一緻,否則資料會有差錯
public Person(Parcel source) {
name = source.readString();
age = source.readInt();
}
//這裡預設傳回0即可
@Override
public int describeContents() {
return 0;
}
//把值寫入Parcel中
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(name);
dest.writeInt(age);
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
//供外部類反序列化本類數組使用
@Override
public Person[] newArray(int size) {
return new Person[size];
}
//從Parcel中讀取資料
@Override
public Person createFromParcel(Parcel source) {
return new Person(source);
}
};
}
Serializable實作與Parcelabel實作的差別
a. Serializable的實作,隻需要implements Serializable即可。這隻是給對象打了一個标記,系統會自動将其序列化。
b. Parcelabel的實作,不僅需要implements Parcelabel,還需要在類中添加一個靜态成員變量CREATOR,這個變量需要實作Parcelable.Creator接口。
2. implements Serializable和Parcelabel的意義
2.1 implements Serializable的意義
對象什麼時候需要進行序列化?
a. 當你想把的記憶體中的對象寫入到硬碟的時候
例如:記憶體不夠用了,那計算機就要将記憶體裡面的一部分對象暫時的儲存到硬碟中,等到要用的時候再讀入到記憶體中,硬碟的那部分存儲空間就是所謂的虛拟記憶體。在比如過你要将某個特定的對象儲存到檔案中,我隔幾天在把它拿出來用,那麼這時候就要實作Serializable接口。
b. 當你想用套接字在網絡上傳送對象的時候
例如:在進行Java的Socket程式設計的時候,你有時候可能要傳輸某一類的對象,那麼也就要實作Serializable接口。最常見的你傳輸一個字元串,它是JDK裡面的類,也實作了Serializable接口,這樣做為的是将資料變為二進制來傳輸,是以可以在網絡上傳輸。
c. 當你想通過RMI傳輸對象的時候
例如:如果要通過遠端的方法調用(RMI)去調用一個遠端對象的方法,如在計算機A中調用另一台計算機B的對象的方法,那麼你需要通過JNDI服務擷取計算機B目标對象的引用,将對象從B傳送到A,就需要實作序列化接口。
一個類隻有實作了Serializable接口,它的對象才是可序列化的。是以如果要序列化某些類的對象,這些類就必須實作Serializable接口。而實際上,Serializable是一個空接口,沒有什麼具體内容,它的目的隻是簡單的辨別一個類的對象可以被序列化。
例如:
public class Test implements Serializable{
private int id;
private String name;
……
}
如果沒有用implements Serializable時,資料以此Test對象封裝存進資料庫,當要取出時,即使SQL在資料庫中能正确傳回資料,但sessionFactory.getCurrentSession().createNativeQuery(SQL,Test.class).list()傳回的資料中字段内容都是空(資料條目數量正常不受影響),進而會導緻諸如Method threw ‘javax.persistence.PersistenceException’ exception.等錯誤。
總結:implements Serializable的意義是實作序列化,保證資料完璧歸趙的取或讀。
2.2 implements Parcelabel的意義
implements Parcelabel的意義和implements Serializable相同,都是實作序列化,差別如下:
a. 在使用記憶體的時候,Parcelable比Serializable性能高,是以推薦使用Parcelable。
b. Serializable在序列化的時候會産生大量的臨時變量,進而引起頻繁的GC。
c. Parcelable不能使用在要将資料存儲在磁盤上的情況,因為Parcelable不能很好的保證資料的持續性在外界有變化的情況下。盡管Serializable效率低點,但此時還是建議使用Serializable。
總結:
實作Serializable和Parcelable都是為了實作序列化,二者的差別展現在兩個地方:
a. 實作Serializable接口非常簡單,聲明一下就可以了;但是實作Parcelable需要重寫writeToParcel方法、重寫describeContents方法、執行個體化靜态内部對象CREATOR實作接口Parcelable.Creator
b. 在使用記憶體的時候,Parcelable比Serializable性能高,是以推薦使用Parcelable。
好文:
https://www.cnblogs.com/renqingping/archive/2012/10/25/Parcelable.html
https://blog.csdn.net/am540/article/details/82498298