Serializable 接口(序列化)

[TOC]java

Serializable 接口(序列化)

前言

查看API文檔時,就會發現Serializable接口是一個標記接口(沒有成員方法和變量),那麼他有什麼用呢?數據庫

  1. 序列化:能夠將一個對象(標誌對象的類型)及其狀態轉換爲字節碼,保存起來(能夠保存在數據庫,內存,文件等),而後能夠在適當的時候再將其狀態恢復(也就是反序列化)
  2. 一個類要想序列化就必須繼承java.io.Serializable接口,同時它的子類也能夠序列化(不用再繼承Serializable接口)。
  3. Serializable接口,不只能夠本機,也能夠網絡操做,它自動屏蔽了操做系統的差別,字節順序等。
  4. 序列化只能保存對象的非靜態成員變量,不能保存任何的成員方法和靜態的成員變量,並且序列化保存的只是變量的值,對於變量的任何修飾符都不能保存。記住序列化是保存對象的狀態。

用途

  • 想把的內存中的對象狀態保存到一個文件中或者數據庫中時候。
  • 想把對象經過網絡進行傳播的時候。

如何實現

  • 原理:Java 序列化技術能夠使你將一個對象的狀態寫入一個Byte 流裏(系列化),而且能夠從其它地方把該Byte 流裏的數據讀出來(反序列化)。
  • 經過ObjectOutputStreamwriteObject()方法把這個類的對象寫到一個地方(文件),再經過ObjectInputStreamreadObject()方法把這個對象讀出來。
  1. 先寫一個實現序列化的類Person
class Person implements Serializable{
    
    //序列化的關鍵常量
	private static final long serialVersionUID = -3911255650485738676L;
	private String name;
	private int age;
	
	public Person() {
		super();
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}
  1. ObjectOutputStreamwriteObject()方法把這個類的對象寫到一個地方,再經過ObjectInputStreamreadObject()方法把這個對象讀出來。
public static void main(String[] args) throws Exception {
		write();
		read();
	}

	public static void read() throws Exception {
		ObjectInputStream ois = new ObjectInputStream(new FileInputStream("oos.txt"));
		Object obj = ois.readObject();
		System.out.println(obj);
		ois.close();
	}

	public static void write() throws Exception {
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("oos.txt"));
		
		Object obj = new Person("老王", 40);
		oos.writeObject(obj);
		
		oos.close();
	}
}

異常

  • java.io.NotSerializableException網絡

    • 名稱:沒有序列化異常
    • 緣由:在將對象保存到文件系統的時候沒有將對象實現序列化接口
    • 解決:針對須要寫入到文件系統的對象實現對應的序列化接口
  • InvalidClassExceptionide

    • 名稱:無效類異常
    • 緣由:文件中保存的流的序列化id和本地類文件的序列化id不匹配(serialVersionUID)
    • 解決:保證id一致性

serialVersionUID

  1. serialVersionUID的取值是Java運行時環境根據類的內部細節自動生成的。若是對類的源代碼做了修改,再從新編譯,新生成的類文件的serialVersionUID的取值有可能也會發生變化。
  2. 類的serialVersionUID的默認值徹底依賴於Java編譯器的實現,對於同一個類,用不一樣的Java編譯器編譯,有可能會致使不一樣的serialVersionUID,也有可能相同。通常給serialVersionUID賦予明確的值。
  3. 當經過網絡傳輸,因serialVersionUID不一致的時候就會報InvalidClassException

transient關鍵字

  • 阻止實例中那些用此關鍵字聲明的變量持久化;當對象被反序列化時(從源文件讀取字節序列進行重構),這樣的實例變量值不會被持久化和恢復。
  • 簡單的說:當某些變量不想被序列化,同是又不適合使用static關鍵字聲明,那麼此時就須要用transient關鍵字來聲明該變量。(不會再反序列化的時候被獲取數據,只會取得初始值,如 int 型的是 0,對象型的是 null。)
class Person implements Serializable{
    
    //序列化的關鍵常量
	private static final long serialVersionUID = -3911255650485738676L;
	private String name;
    //反序列化時不會獲取age值
	private transient int age;
	
	public Person() {
		super();
	}

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

以上this

@Fzxeyspa

相關文章
相關標籤/搜索