1. 程式人生 > >(雜記)Java序列化Serializable和反序列化

(雜記)Java序列化Serializable和反序列化

1.什麼是java序列化?

把物件轉化為位元組序列的過程稱為序列化 把位元組序列轉化為物件的過程稱為反序列化。

2.為什麼需要序列化?

序列化主要有兩個應用場景:
  1. 用於把物件從記憶體中儲存到磁碟中。
  2. 用於網路上傳輸物件 此處舉例解釋一下:比如Web開發中經常遇到的Session物件儲存問題,假設有10W個併發請求到來,記憶體短時間內生成10W個Session物件是吃不消的,怎麼辦呢?先把這10W個Session物件永久性地儲存到磁碟,那麼短時間內,根據到來的請求,逐個在記憶體中還原Session物件,此時,在磁盤裡儲存的最好的是Java序列化物件,最小化佔據磁碟記憶體。 再說遠端網路通訊,網路上資料都是二進位制序列形式,一般請求方會發送java物件的位元組序列,接收方根據位元組序列還原java物件。好處是什麼?物件的位元組序列記憶體遠小於物件記憶體,可以縮短請求-響應耗時。
注意事項
3. 假如物件中包含有物件屬性,那麼該物件的類也要實現Serializable介面,否則該物件無法實現序列化。 4. 序列化操作會忽略靜態變數的狀態,舉例說物件中的static屬性不能被序列化,static屬性是類級別的,不是物件級別的。

3.序列化過程與程式碼示例

首先介紹一下要用到的JDK類庫中的API:

1.java.io.OutputStream物件輸出流,通過該類(或其子類FileOutputStream,ByteOutputStream)建立一個可被序列化的物件,然後將該物件傳遞給java.io.ObjectOutputStream物件,該物件的writeObject()方法接受一個OutputStream物件,完成序列化過程。 2.java.io.InputStream物件輸入流,接受一個物件輸入流,然後呼叫java.io.ObjectInputStream.readObject()方法,完成發序列化。(詳見程式碼栗子)

java序列化物件程式碼
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class SerializeInstance implements Serializable {

	/**
	 * the default serialVersion UID;
	 */
	private static final long serialVersionUID = 1L;
	public int num = 1209;
	public static void main(String []args)   {
		try {
			//1.the process of the serializing 
			FileOutputStream fileOutputStream = new FileOutputStream("D:\\JavaCodes\\Examps\\JasonWord.txt");
			ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);
			 SerializeInstance instance = new SerializeInstance();
			 outputStream.writeObject(instance);
			 outputStream.flush();
			 outputStream.close();
			 
		}catch(IOException e) {
			e.printStackTrace();
		}
		
		try {
			//2.The Process of the deSerializing
			FileInputStream fileInputStream = new FileInputStream("D:\\JavaCodes\\Examps\\JasonWord.txt");
			ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
			SerializeInstance instance02 = (SerializeInstance)objectInputStream.readObject();
			System.out.println(instance02.num + "WuLiWaLa");
			
		}catch (IOException | ClassNotFoundException e) {
			 e.printStackTrace();
		}
		System.out.println("Hello World! ");
	}
	
}
補充知識:serialVersionUID是什麼用?
這篇部落格 的最後部分解釋了serialVersionUID的用處和程式碼驗證,這裡做一個簡單的總結:serialVersionUID是一個類的序列化版本號, 實現Serializable介面的類,都必須有這個欄位(意思是要麼手動指定一個,要麼在警告的情況下,編譯器預設給生成一個,反正得有一個),而且必須是private static final long 資料型別的。有什麼用呢?它就像是一把鑰匙,只對應某一個物件,反序列化時需要它進行解密。 為了提高serialVersionUID的獨立性和確定性,強烈建議在一個可序列化類中顯示的定義serialVersionUID,為它賦予明確的值。

顯式地定義serialVersionUID有兩種用途:     1、 在某些場合,希望類的不同版本對序列化相容,因此需要確保類的不同版本具有相同的serialVersionUID;     2、 在某些場合,不希望類的不同版本對序列化相容,因此需要確保類的不同版本具有不同的serialVersionUID。     

本文在寫作過程中,主要參考了以下部落格內容,歡迎大家前去參閱: 1.只為成功找方法,不為失敗找藉口:https://www.cnblogs.com/xdp-gacl/p/3777987.html 2.飛飛飛:https://www.cnblogs.com/gtaxmjld/p/4866931.html