(雜記)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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章