1. 程式人生 > >java中io流(二)

java中io流(二)

序列化與反序列化:

1.概念:

序列化:將物件的狀態儲存到特定介質的過程。也就是將物件的狀態轉換為可傳輸(流)的過程!

序列化 -------》 寫入(輸出流)

反序列化:從特定儲存介質中讀取資料並重新構建成物件的過程!也就是把流解析成物件的方式!

反序列化------》讀取 (輸入流)

2.關鍵物件

  • 序列化:ObjectOutputStream,輸出流物件.writeObject(自定義類的物件/集合);

  • 反序列化:ObjectInputStream,輸入流物件.readObject()

  • 注意:序列化必須要實現Serializable介面,反序列化要進行強制型別轉換,因為返回的是一個Object型別的物件!

3.程式碼如下

//學生類:實現了序列化介面Serializable
public class Student implements Serializable{
	
	private int id;
	private String name;
	private String pwd;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	
	public Student() {
		
	}
	
	public Student(int id,String name,String pwd ) {
		this.id=id;
		this.name=name;
		this.pwd=pwd;
	}

	/**
	 * 重寫toString 方法
	 */
	public String toString() {
		return "學號:" + id + ", 姓名:" + name + ", 密碼:" + pwd;
	}
	
}

//測試類:
public class Test {
	public static void main(String[] args) {
		//建立集合物件
		ArrayList <Student> list=new ArrayList<Student>();
		//建立學生類物件
		Student stu1=new Student(11,"張三","123456");
		Student stu2=new Student(12,"李四","024966");
		Student stu3=new Student(13,"王五","386436");
		
		//新增集合物件
		list.add(stu1);
		list.add(stu2);
		list.add(stu3);
		//聲名序列化物件,
		ObjectOutputStream oos=null;
		ObjectInputStream ois=null;
		try {
			//1.序列化
			//建立序列化物件輸出流,寫入資料
			oos=new ObjectOutputStream(new FileOutputStream("學生.txt"));
			
			
			//寫入物件(集合)
			oos.writeObject(list);
			
			
			//2.反序列化
			//建立反序列化物件輸入流,讀取資料
			ois=new ObjectInputStream(new FileInputStream("學生.txt"));
			
			//讀取集合中的物件,得到的是Object型別
			Object obj=ois.readObject();
			
			//將集合中的obj型別強制轉換成Student型別
			ArrayList<Student> stuList=(ArrayList<Student>) obj;
			
			//迴圈讀取集合中的物件
			for (int i = 0; i < list.size(); i++) {
				Student stu=stuList.get(i);
				System.out.println(stu);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} finally {
			try {
				//關閉流
				ois.close();
				oos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		
	}
}



輸出結果:

注意:

  • 如果出於安全考慮,某些屬性要限制不能序列化,就需要使用transient關鍵字修飾屬性!
  • 如果在向檔案中使用序列化機制寫入多個物件,那麼反序列化恢復物件時,必須按照寫入的順序讀取。
  • 如果一個可序列化的類,有多個父類(包括直接或者間接父類),則這些父類要麼是可序列化的,要麼有無參構造器,否則會丟擲異常!

4.物件引用的序列化:

  • 所有儲存到磁碟中的物件都有一個序列號
  • 當程式檢視序列化一個物件時,將會檢查是否已經序列化,只有序列化後的物件才能被轉換成位元組序列輸出,否則報NotSerializableException異常
  • 如果物件已經被序列化,則程式直接輸出一個序列化編號,而不再重新序列化。