Java 序列化Serializable具體解釋(附具體範例)

來源:互聯網
上載者:User

標籤:main   儲存   ransient   使用   名稱   soft   stack   new   微軟   

                                                 Java 序列化Serializable具體解釋(附具體範例) 

1、什麼是序列化和還原序列化
Serialization(序列化)是一種將對象以一連串的位元組描寫敘述的過程;還原序列化deserialization是一種將這些位元組重建成一個對象的過程。


2、什麼情況下須要序列化 
a)當你想把的記憶體中的對象儲存到一個檔案裡或者資料庫中時候。
b)當你想用通訊端在網路上傳送對象的時候;
c)當你想通過RMI傳輸對象的時候。

3、怎樣實現序列化

將須要序列化的類實現Serializable介面就能夠了。Serializable介面中沒有不論什麼方法,能夠理解為一個標記,即表明這個類能夠序列化。


4、序列化和還原序列化範例

假設我們想要序列化一個對象,首先要建立某些OutputStream(如FileOutputStream、ByteArrayOutputStream等),然後將這些OutputStream封裝在一個ObjectOutputStream中。

這時候,僅僅須要調用writeObject()方法就能夠將對象序列化。並將其發送給OutputStream記住:對象的序列化是基於位元組的,不能使用Reader和Writer等基於字元的階層。而反序列的過程(即將一個序列還原成為一個對象),須要將一個InputStream(如FileInputstream、ByteArrayInputStream等)封裝在ObjectInputStream內,然後調用readObject()就可以。

package com.sheepmu;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;public class MyTest implements Serializable{private static final long serialVersionUID = 1L;private String name="SheepMu";private int age=24;public static void main(String[] args){//以下代碼實現序列化try {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//輸出資料流儲存的檔案名稱為 my.out ;ObjectOutputStream能把Object輸出成Byte流MyTest myTest=new MyTest();oos.writeObject(myTest); oos.flush();  //緩衝流 oos.close(); //關閉流} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) {e.printStackTrace();} fan();//調用以下的  還原序列化  代碼}public static void fan()//反序列的過程{          ObjectInputStream oin = null;//局部變數必需要初始化try{oin = new ObjectInputStream(new FileInputStream("my.out"));} catch (FileNotFoundException e1){ e1.printStackTrace();} catch (IOException e1){e1.printStackTrace();}              MyTest mts = null;try {mts = (MyTest ) oin.readObject();//由Object對象向下轉型為MyTest對象} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}              System.out.println("name="+mts.name);             System.out.println("age="+mts.age);    }}
會在此項目的工作空間產生一個 my.out檔案。

序列化後的內容稍後補齊。先看還原序列化後輸出例如以下:

name=SheepMu
age=24

5、序列化ID

序列化 ID 在 Eclipse 下提供了兩種建置原則,一個是固定的 1L,一個是隨機產生一個不反覆的 long 類型資料(實際上是使用 JDK 工具產生)。在這裡有一個建議,假設沒有特殊需求,就是用預設的 1L 就能夠,這樣能夠確保代碼一致時還原序列化成功。這也可能是造成序列化和還原序列化失敗的原因。由於不同的序列化id之間不能進行序列化和還原序列化。


6.序列化前和序列化後的對象的關係

是 "=="還是equal? or  是淺複製還是深複製? 

答案:深複製,還原序列化還原後的對象地址與原來的的地址不同

序列化前後對象的地址不同了,可是內容是一樣的。並且對象中包括的引用也同樣。

換句話說,通過序列化操作,我們能夠實現對不論什麼可Serializable對象的”深度複製(deep copy)"——這意味著我們複製的是整個對象網。而不僅僅是基本對象及其引用。對於同一流的對象,他們的地址是同樣,說明他們是同一個對象,可是與其它流的對象地址卻不同樣。

也就說,僅僅要將對象序列化到單一流中,就能夠恢複出與我們寫出時一樣的對象網,並且僅僅要在同一流中。對象都是同一個。


7.靜態變數是否能序列化

若把上面的代碼中的 age變數前加上 static ,輸出任然是

name=SheepMu
age=24

可是看以下的範例:

package com.sheepmu;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.io.Serializable;public class MyTest implements Serializable{private static final long serialVersionUID = 1L;private String name="SheepMu";private static int age=24;public static void main(String[] args){//以下代碼實現序列化try {ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("my.out"));//輸出資料流儲存的檔案名稱為 my.out 。ObjectOutputStream能把Object輸出成Byte流MyTest myTest=new MyTest();oos.writeObject(myTest); oos.flush();  //緩衝流 oos.close(); //關閉流} catch (FileNotFoundException e) { e.printStackTrace();} catch (IOException e) {e.printStackTrace();} fan();//調用以下的  還原序列化  代碼}public static void fan(){new MyTest().name="SheepMu_1";     //!!!!!!!!!!!!!!!!重點看這兩行 更改部分age=1;        //!!!!!!!!!!!!!!!!!!!重點看這兩行 更改部分          ObjectInputStream oin = null;//局部變數必需要初始化try{oin = new ObjectInputStream(new FileInputStream("my.out"));} catch (FileNotFoundException e1){ e1.printStackTrace();} catch (IOException e1){e1.printStackTrace();}              MyTest mts = null;try {mts = (MyTest ) oin.readObject();//由Object對象向下轉型為MyTest對象} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}              System.out.println("name="+mts.name);             System.out.println("age="+mts.age);    }}
輸出結果為:

name=SheepMu
age=1
為何把最上面代碼的age變數添上static 後還是還原序列化出了24呢?而新的從新對變數賦值的代碼,不是static的得到了序列化本身的值。而static的則得到的是從新附的值。原因: 序列化會忽略靜態變數,即序列化不儲存靜態變數的狀態。靜態成員屬於類層級的,所以不能序列化。即 序列化的是對象的狀態不是類的狀態。這裡的不能序列化的意思。是序列化資訊中不包括這個靜態成員域。

最上面加入了static後之所以還是輸出24是由於該值是JVM載入該類時分配的值。

註:transient後的變數也不能序列化。可是情況稍複雜,稍後開篇說。

8、總結:

a)當一個父類實現序列化,子類自己主動實現序列化,不須要顯式實現Serializable介面。

b)當一個對象的執行個體變數引用其它對象,序列化該對象時也把引用對象進行序列化。

c) static,transient後的變數不能被序列化;



 

Java 序列化Serializable具體解釋(附具體範例)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.