1. 程式人生 > >Java之Serializable介面-201804

Java之Serializable介面-201804

序列化-Serializable介面

1.概念

    序列化-將物件轉化成位元組序列的過程。

    反序列化-將位元組序列恢復成物件的過程。

2.目的

    Java平臺允許我們在記憶體中建立可複用的Java物件,但只有當JVM(Java虛擬機器)處於執行時,這些物件才可能存在,也就是這些物件的生命週期不會比JVM的生命週期更長。但在現實應用中,就可能要求在JVM停止執行之後能夠儲存指定的物件(持久化物件),並在將來重新讀取被儲存的物件。Java物件序列化就實現了該功能。        

     所以序列化機制會把記憶體中的Java物件轉換成與平臺無關的二進位制流,從而永久地儲存在磁碟上或是通過網路傳輸到另一個網路節點。

3.方法

    a. 把記憶體中的物件存到硬碟中或資料庫中

    b.使用socket進行物件的網路傳輸

    c.通過RMI傳輸物件

4.具體例項

    Servlet中HttpSession物件:每次使用者訪問產生會話都會生成一個HttpSession物件。當大量使用者同時訪問時,產生大量HttpSession物件,消耗伺服器記憶體資源。且只有在這些HttpSession超時後,伺服器才能釋放記憶體。

    因此,伺服器通常把那些暫時不活動但未超時的HttpSession採用序列化的方式儲存到檔案系統或資料庫中。等到伺服器要使用這些HttpSession時,再通過反序列化的方式載入入記憶體。這項技術稱為Session的持久化。

5.serialVersionUID

    如果serialVersionUID沒有顯式生成,系統就會自動生成一個。此時,如果在序列化後我們將該類作新增或減少一個欄位等的操作,系統在反序列化時會重新生成一個serialVersionUID然後去和已經序列化的物件進行比較,就會報序列號版本不一致的錯誤。為了避免這種問題, 一般系統都會要求實現serialiable介面的類顯式的生明一個serialVersionUID。 

    顯式定義serialVersionUID的兩種用途: 
   1、 希望類的不同版本對序列化相容時,需要確保類的不同版本具有相同的serialVersionUID; 
   2、 

不希望類的不同版本對序列化相容時,需要確保類的不同版本具有不同的serialVersionUID。

6.transient關鍵字

    transient修飾瞬態屬性,表示該屬性不會被序列化。

    當物件A被序列化時,將依次序列化其各個屬性。當某屬性引用到另一個物件B時,該物件B也將被序列化。若物件B的某屬性引用到物件C時,物件C也將被序列化。這就是遞迴序列化。

7.writeObject與readObject方法

    a.public final void writeObject(Object obj) throws IOException

    將指定的物件寫入 ObjectOutputStream。物件的類、類的簽名,以及類及其所有超型別的非瞬態和非靜態欄位的值都將被寫入。可以使用 writeObject 和 readObject 方法重寫類的預設序列化。由此物件引用的物件是以可變遷的方式寫入的,這樣,可以通過 ObjectInputStream 重新構造這些物件的完全等價的圖形。

    b. public final Object readObject() throws IOException, ClassNotFoundException

    從 ObjectInputStream 讀取物件。物件的類、類的簽名和類及所有其超型別的非瞬態和非靜態欄位的值都將被讀取。可以使用 writeObject 和 readObject 方法為類重寫預設的反序列化。由此物件引用的物件是可傳遞讀取的,這樣 readObject 即可重新構造這些物件的完全等價的圖形。

8.注意事項

    a.物件的類名、屬性都會被序列化;而方法、static屬性、transient屬性都不會被序列化.

    b.要序列化的物件的引用屬性也必須是可序列化的,否則該物件不可序列化,除非transient關鍵字修飾該屬性.

    c.反序列化地象時必須有序列化物件生成的class檔案(很多沒有被序列化的資料需要從class檔案獲取)

    d.當通過檔案、網路來讀取序列化後的物件時,必須按實際的寫入順序讀取。

    e.反序列化機制無需通過構造器來初始Java物件。 

9.測試程式碼
public class SerializableTest {
	public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
		Tin persi=new Tin("persi","blue","百事",1);
		Tin coke=new Tin("coke","red","可口",2);
		BigTin rio=new BigTin("rio","yellow","銳歐",1,200,350);
		BigTin rioK=new BigTin("rio","orange","銳歐",2,250,350);
		rio.setTin(persi);
		rioK.setTin(coke);
		System.out.println(rio);
		System.out.println(rioK);
		//序列化
		ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream(new File("E:/serial.txt")));
		oos.writeObject(rio);
		//oos.writeObject(rioK); ////注意可以寫入多個物件,但需要按順序讀取;否則會導致資料讀取失敗;
		oos.writeInt(66);
		oos.close();
		System.out.println("serial successfully");
		//反序列化
		ObjectInputStream ois=new ObjectInputStream(new FileInputStream(new File("E:/serial.txt")));
		BigTin rio2=(BigTin)ois.readObject();
		int out=ois.readInt();
		ois.close();
		System.out.println(rio==rio2);
		System.out.println(rio.equals(rio2));
		System.out.println("deserial successfully");
		System.out.println(out);
		System.out.println(rio2);
	}
}

class BigTin extends Tin{
	/**
	 * 
	 */
	private static final long serialVersionUID = 263190832386845089L;
	public BigTin(String name, String color, String brand, int num,int height,int weight) {
		super(name, color, brand, num);
		// TODO Auto-generated constructor stub
		this.weight=weight;
		BigTin.height=height;
	}

	@Override
	public String toString() {
		return "BigTin [tin=" + tin + ", height=" + height + ", weight=" + weight + ", name=" + name + ", color="
				+ color + ", brand=" + brand + ", num=" + num + "]";
	}

	Tin tin;
	static int height;
	transient int weight;
	public Tin getTin() {
		return tin;
	}
	public void setTin(Tin tin) {
		this.tin = tin;
	}
	
	
	
}

class Tin implements Serializable{
	/**
	 * 
	 */
	private static final long serialVersionUID = 2947592207173916450L;
	
	String name;
	String color;
	String brand;
	transient int num;
	public Tin(String name, String color, String brand, int num) {
		super();
		this.name = name;
		this.color = color;
		this.brand = brand;
		this.num = num;
	}
	@Override
	public String toString() {
		return "Tin [name=" + name + ", color=" + color + ", brand=" + brand + ", num=" + num + "]";
	}

}

結果:

BigTin [tin=Tin [name=persi, color=blue, brand=百事, num=1], height=250, weight=350, name=rio, color=yellow, brand=銳歐, num=1]
BigTin [tin=Tin [name=coke, color=red, brand=可口, num=2], height=250, weight=350, name=rio, color=orange, brand=銳歐, num=2]
serial successfully        
false
false
deserial successfully
66
BigTin [tin=Tin [name=persi, color=blue, brand=百事, num=0], height=250, weight=0, name=rio, color=yellow, brand=銳歐, num=0]
Wed Apr 25 09:23:26 CST 2018

參考:https://bbs.csdn.net/topics/390155251/

        https://blog.csdn.net/zcl_love_wx/article/details/52126876

相關推薦

JavaSerializable介面-201804

序列化-Serializable介面1.概念    序列化-將物件轉化成位元組序列的過程。    反序列化-將位元組序列恢復成物件的過程。2.目的    Java平臺允許我們在記憶體中建立可複用的Java物件,但只有當JVM(Java虛擬機器)處於執行時,這些物件才可能存在,

Java Serializable 序列化和反序列化的概念,作用的通俗易懂的解釋

計算 transient 全部 序列化對象 語義 meta person int 較高的 遇到這個 Java Serializable 序列化這個接口,我們可能會有如下的問題a,什麽叫序列化和反序列化b,作用。為啥要實現這個 Serializable 接口,也就是為啥要序列

Java Serializable 序列化和反序列化的概念 通俗易懂!!!

轉自: https://blog.csdn.net/qq_27093465/article/details/78544505 遇到這個 Java Serializable 序列化這個介面,我們可能會有如下的問題a,什麼叫序列化和反序列化 b,作用。為啥要實現這個 Serializable

JDK1.8 java.io.Serializable介面詳解

java.io.Serializable介面是一個標誌性介面,在介面內部沒有定義任何屬性與方法。只是用於標識此介面的實現類可以被序列化與反序列化。但是它的奧祕並非像它表現的這樣簡單。現在從以下幾個問題入手來考慮。 希望物件的某些屬性不參與序列化應該怎麼處理? 物件序列化之後,如果類的屬性

Java“面向介面程式設計”-2

補充(2018-12-09): 其實介面的另外一個概念就是監聽,比如我要從一個地方獲取某個引數的狀態,其實有很多種方法例如:事件匯流排、廣播、介面監聽等。而在這些方法中使用介面無疑是代價(程式碼量以及過程中消耗的時間)最小的。 還是使用程式碼演示吧: 思路:建立一個單例模式的類,任何呼叫

java實現serializable介面的作用

一個物件序列化的介面,一個類只有實現了Serializable介面,它的物件才是可序列化的。因此如果要序列化某些類的物件,這些類就必須實現Serializable介面。而實際上,Serializable是一個空介面,沒有什麼具體內容,它的目的只是簡單的標識一個類的物件可以被

javaType介面及其子介面

一. Type介面概述 自從JDK1.5引入了泛型後,我們便多了一個表示型別的介面,即Type介面。Type 是 Java 程式語言中所有型別的公共高階介面。它們包括原始型別、引數化型別、陣列型別、型別變數和基本型別。該介面只有一個預設的方法,表示對該介面的描述,比如引數型

Javaswing介面

Java提供了swing圖形使用者介面,下面主要了解Swing和AWT的一些元件的用法 import java.awt.*; import javax.swing.*; @SuppressWarnings("serial") class Frame extends JFrame{

JAVA常用集合框架用法詳解基礎篇一Colletion介面

首先,在學習集合之前我們能夠使用的可以儲存多個元素的容器就是陣列。 下面舉幾個例子主要是引出集合類的: 1、8,4,5,6,7,55,7,8  像這樣的型別相同的可以使用陣列來儲存,本例可以用int[] arr來儲存。 2、”zhnagsan”,true,68 像這樣的可以使

JAVA面向物件程式設計購物車介面的設計與功能的實現

1、小組成員及分工 小組成員 負責工作 蘭澤祥 負責總體介面、Git程式碼庫 吳修恩 負責MVC模式、類名包名的規範化 2、Git 倉庫地址 倉庫地址:https://gitee

Java併發程式設計鎖機制Condition介面

前言 在前面的文章中,我曾提到過,整個Lock介面下實現的鎖機制中AQS(AbstractQueuedSynchronizer,下文都稱之為AQS)與Condition才是真正的實現者。也就說Condition在整個同步元件的基礎框架中也起著非常重要的作用,既然它如此重要與犀利,那麼現在我

Java 集合學習——Java 的Iterable介面的使用

參考:https://www.cnblogs.com/LittleHann/p/3690187.html 雖然知道Iterable介面可以用來遍歷集合類中的內容,但是具體操作時還是遇到下面的問題了,   你知道Iterable預設指標指的的第一個物件還是,指標變數呢?看完下

Java集合系列List介面

List是一個有序的佇列,每一個元素都有它的索引。第一個元素的索引值是0。List的實現類有LinkedList, ArrayList, Vector, Stack。 List抽象資料型別: ADT List Data 線性表的元素集合為{a1,a2,a3,a4....an},資料型別都是DataTyp

java 介面的簡單使用方法———停車場是否可以停下車的問題

public class Parkinglot{ public static void main(String[] args){ Parking parking = new Parking(8,4); Car bus = new Bus(); parking.park(b

java-圖形使用者介面(GUI)AWT程式設計-整體思路與程式碼架構

1、整體思路   任何視窗都可以被分解成一個空的容器,容器中盛放了大量的基本元件,通過設定這些基本元件的大小、位置等屬性,就可以將該空的容器和基本元件組成一個整體的視窗。具體實現思路:   1)建立一個Frame頂層視窗   2)設定頂層視窗的佈局(如果需要的話):f.setLayout(new xxx

Java Web--增刪改查介面後臺java程式碼(轉載參考)

/**  *   */ /**  * @author Administrator  *  */ package dao; import java.sql.*; public

Java路:介面

介面 介面(interface)是Java所提供的另一種重要技術,是一種特殊的類,它的結構和抽象類非常相似,也具有資料成員與抽象方法,但它與抽象類又有不同,並且Java 8中又添加了新特性。 ,而方法會被隱式地指定為public abstract方法且只能是public abstract

Java路:抽象類與介面對比

先上圖: 下面詳細說下: 1、相同點 (1)都是抽象型別; (2)都可以有實現方法;抽象類中可以實現普通方法,介面中可以實現預設方法(Java 8)。 (3) 都可以不需要實現類或者繼承者去實現所有方法。(以前不行,現在介面中預設方法不需

java 物件實現序列化 Serializable()介面

總結一下Serializable介面的實現原理。 當一個類實現了Seializable介面(該介面僅為標記介面,不包含任何方法定義),表示該類可以序列化,序列化的目的是將一個實現了Serializable介面的物件可以轉換成一個位元組序列,儲存物件的狀態。 把該位元組序列

【修真院java小課堂】什麼是序列化和反序列化,在RMI中是否要實現 SERIALIZABLE 介面, SERIALVERSIONUID的用處是什麼?

8.更多討論 1、serialVersionUID實際作用 假設本地資料庫中儲存了大量的user物件,後來由於需求,要修改User類中的屬性;如果不設定SerialVersionUID,根據屬性方法等自動生成,就會出現程式碼演示中的錯誤,造