序列化是指將對象的狀態信息轉換爲能夠存儲或傳輸的形式的過程。java
在Java中建立的對象,只要沒有被回收就能夠被複用,可是,建立的這些對象都是存在於JVM的堆內存中,JVM處於運行狀態時候,這些對象能夠複用,android
可是一旦JVM中止,這些對象的狀態也就丟失了。git
在實際生活中,須要將對象持久化,須要的時候再從新讀取出來,經過對象序列化,能夠將對象的狀態保存爲字節數組,須要的時候再將字節數組反序列化爲對象。github
對象序列化能夠很容易的在JVM中的活動對象和字節數組(流)之間轉換,普遍用於RMI(遠程方法調用)以及網絡傳輸中。數組
特別注意:網絡
a.靜態成員變量屬於類不屬於對象,因此不會參與序列化(對象序列化保存的是對象的「狀態」,也就是它的成員變量,所以序列化不會關注靜態變量)ide
b.用transient關鍵字標記的成員變量不參與序列化(在被反序列化後,transient 變量的值被設爲初始值,如 int 型的是 0,對象型的是 null)性能
(1).Serializableui
1 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission> 2 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
1 import java.io.Serializable; 2 3 public class StudentSerializable implements Serializable { 4 5 //指定serialVersionUID, 6 //由於原則上序列化後的數據中的serialVersionUID只有和當前類的serialVersionUID相同時才能被正常的反序列化 7 //最好本身指定UID或者系統生成,由於若是增長或者刪除了某些成員變量,那麼系統就會從新生成hash值而後賦給UID,致使反序列化時候crash 8 private static final long serialVersionUID = 10000000000000000L; 9 10 private int Uid; 11 private String Name ; 12 13 public int getUid() { 14 return Uid; 15 } 16 public void setUid(int uid) { 17 Uid = uid; 18 } 19 public String getName() { 20 return Name; 21 } 22 public void setName(String name) { 23 Name = name; 24 } 25 @Override 26 public String toString() { 27 return "StudentSerializable [Uid=" + Uid + ", Name=" + Name + "]"; 28 } 29 30 }
1 private void DealSerializable() throws IOException { 2 // Initializes The Object 3 StudentSerializable stu = new StudentSerializable(); 4 stu.setUid(9027); 5 stu.setName("fish"); 6 7 File extDir = Environment.getExternalStorageDirectory(); 8 String filename = "tempFile.txt"; 9 File fullFilename = new File(extDir, filename); 10 11 try { 12 fullFilename.createNewFile(); 13 fullFilename.setWritable(Boolean.TRUE); 14 fullFilename.setReadable(Boolean.TRUE); 15 16 } catch (IOException e) { 17 // TODO Auto-generated catch block 18 e.printStackTrace(); 19 } 20 21 // Write Obj to File 22 ObjectOutputStream oos = null; 23 try { 24 oos = new ObjectOutputStream(new FileOutputStream(fullFilename.getAbsoluteFile())); 25 oos.writeObject(stu); 26 } catch (IOException e) { 27 e.printStackTrace(); 28 } finally { 29 //oos.close(); 30 } 31 32 // Read Obj from File 33 //File file = new File("tempFile.txt"); 34 ObjectInputStream ois = null; 35 try { 36 ois = new ObjectInputStream(new FileInputStream(fullFilename.getAbsoluteFile())); 37 StudentSerializable newStu = (StudentSerializable) ois.readObject(); 38 System.out.println(newStu); 39 } catch (IOException e) { 40 e.printStackTrace(); 41 } catch (ClassNotFoundException e) { 42 e.printStackTrace(); 43 } finally { 44 //ois.close(); 45 } 46 }
在使用時,一般是和ObjectOutputStream
以及 ObjectInputStream
配套一塊兒使用,準確的說是和ObjectOutputStream
裏的writeObject ()
和 ObjectInputStream
裏的 readObject ()
一塊兒使用。writeObject()
方法是最重要的方法,用於對象序列化。若是對象包含其餘對象的引用,則writeObject()方法遞歸序列化這些對象。this
(2).Parcelable
1 import android.os.Parcel; 2 import android.os.Parcelable; 3 4 public class StudentParcelable implements Parcelable{ 5 6 private int Uid; 7 private String Name ; 8 9 private Book book ; 10 11 public StudentParcelable(int uid, String name) { 12 super(); 13 Uid = uid; 14 Name = name; 15 } 16 17 public int getUid() { 18 return Uid; 19 } 20 public void setUid(int uid) { 21 Uid = uid; 22 } 23 public String getName() { 24 return Name; 25 } 26 public void setName(String name) { 27 Name = name; 28 } 29 30 31 //功能:返回當前對象的內容描述,若是含有文件描述符,返回1 32 //即CONTENTS_FILE_DESCRIPTOR 33 //幾乎全部狀況都會返回0 34 @Override 35 public int describeContents() { 36 // TODO Auto-generated method stub 37 return 0; 38 } 39 40 /** 41 * 序列化功能由writeToParcel完成,最終經過Parcel的一系列Write方法完成 42 */ 43 //功能:將當前對象寫入序列化結構中,其中flags標識有兩種值,0或1 44 //爲1時標識當前對象須要做爲返回值返回,不能馬上釋放資源,即PARCELABLE_WRITE_RETURN_VALUE 45 //不過幾乎全部狀況都爲0 46 @Override 47 public void writeToParcel(Parcel dest, int flags) { 48 // TODO Auto-generated method stub 49 dest.writeInt(Uid); 50 dest.writeString(Name); 51 dest.writeParcelable(book, 0); 52 } 53 54 /** 55 * 反序列化由CREATOR來完成,其內部標明瞭如何建立序列化對象和數組 56 * 並經過Parcel的一系列read方法來完成反序列化 57 */ 58 public StudentParcelable(Parcel source){ 59 Uid = source.readInt(); 60 Name = source.readString(); 61 62 //注意:book是一個可序列化對象,因此它的反序列化過程須要傳遞當前線程的上下文類加載器 63 //不然會報找不到類的錯誤 64 book = source.readParcelable(Thread.currentThread().getContextClassLoader()); 65 } 66 67 public static final Parcelable.Creator<StudentParcelable> CREATOR = new Parcelable.Creator<StudentParcelable>() { 68 69 //功能: 從Parcel容器中讀取傳遞數據值,封裝成Parcelable對象返回邏輯層。 70 @Override 71 public StudentParcelable createFromParcel(Parcel source) { 72 // TODO Auto-generated method stub 73 return new StudentParcelable(source); 74 } 75 76 //功能:建立一個類型爲T,長度爲size的數組,僅一句話(return new T[size])便可。方法是供外部類反序列化本類數組使用。 77 @Override 78 public StudentParcelable[] newArray(int size) { 79 // TODO Auto-generated method stub 80 return new StudentParcelable[size]; 81 } 82 }; 83 84 85 }
1 Intent intent = new Intent(this,Second.class); 2 StudentParcelable stu = new StudentParcelable(001,"fish"); 3 intent.putExtra("student", stu); 4 startActivity(intent);
1 Intent intent = getIntent(); 2 StudentParcelable stu = (StudentParcelable) intent.getParcelableExtra("student"); 3 Log.i("LOG", "student name :" + stu.getName()); 4 Log.i("LOG", "student age :" + stu.getUid());
二者區別:
1.Serializable實現簡單,而Parcelable須要實現特殊的接口
2.Serializable將對象轉化爲字節流存儲在外部設備,須要時從新生成對象(依靠反射),由於使用反射,因此會產生大量的臨時變量,從而引發頻繁的GC,相比之下Parcelable性能更高,Parcelable的效率是Serializable的十倍以上,因此在內存中傳輸時更推薦Parcelable(好比在網絡中傳輸對象或者進程間傳輸對象,還有Intent)
3.Parcelable的整個過程都在內存中進行,反序列化讀取的就是原對象,不會建立新對象。要注意的是:不能使用要將數據存儲在磁盤上(好比永久性保存對象,或者保存對象的字節序列到本地文件中),由於Parcel是爲了更好的實如今IPC間傳遞對象,並非一個通用的序列化機制,當改變任何Parcel中數據的底層實現均可能致使以前的數據不可讀取(Parcelable 是以2進制的方式寫入,嚴重依賴寫入順序),還有就是Parcelable爲了效率徹底沒有考慮版本間的兼容性,因此數據持久化仍是要使用Serializable(好比外部設備保存對象狀態或者網絡傳輸對象)
快速解析和序列化Json對象的類庫:LoganSquare
注意:
1.若是一個類想被序列化,須要實現Serializable接口。不然將拋出NotSerializableException
異常,這是由於,在序列化操做過程當中會對類型進行檢查,要求被序列化的類必須屬於Enum、Array和Serializable類型其中的任何一種,這也是爲何Serializable雖然是一個空接口,可是隻要實現了該接口就能序列化和反序列化。
2.在類中增長writeObject 和 readObject 方法能夠實現自定義序列化策略,雖然這倆方法不是被顯示調用,可是由於在使用ObjectOutputStream的writeObject方法和ObjectInputStream的readObject方法時,會經過反射的方式調用到它們。
參考:http://www.hollischuang.com/archives/1140#What%20Serializable%20Did