1. 程式人生 > >java序列化流:序列化與逆序列化

java序列化流:序列化與逆序列化

package com.qianfeng.test;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

/*
 * 序列化流:將短期儲存的資料實現長期儲存的過程
 * 
 * 短期儲存:資料存放在記憶體中,資料會隨著程式的關閉而釋放----物件,陣列,集合,變數
 * 長期儲存:資料存放在磁碟中,即使程式關閉了,資料依然存在----檔案
 * 
 * 序列化:將資料從記憶體存入磁碟,可以實現資料的持久化儲存.
 * 逆序列化:將資料從磁碟傳回記憶體.
 * 
 * 進行序列化的步驟:---以物件的序列化為例項講解
 * 1.建立一個類
 * 2.使用對應的流將物件存入磁碟---序列化---ObjectOutputStream
 * 3.使用對應的流將資料從磁碟中取出放回記憶體---逆序列化-----ObjectInputStream
 * 4.關閉流
 * 
 * 注意:序列化流在工作時也要關聯輸入流和輸出流
 * 
//建立類用於序列化
//類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。
//可序列化類的所有子型別本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。
/*
 * 解釋:
 * 一個類如果沒有實現Serializable,進行序列化會報異常:NotSerializableException
 * 
 * 實現了Serializable介面的類可以達到的目的:
 * 1.可以進行序列化
 * 2.進行序列化的類的元素都必須支援序列化
 * 3.介面本身沒有方法或欄位,只是用來表示可序列化的語義
 * 
 * * 注意點:
 * 1. ClassNotFoundException:當前的類沒有找到
 * 分析:將Person物件進行序列化之後,將Person類刪除,再進行反序列化的時候出現了異常
 * 原因:反序列化在執行的時候依賴位元組碼檔案,當類沒有了,位元組碼檔案無法建立,反序列化失敗
 * 
 * 2.java.io.InvalidClassException  無效的類
 * 出現的原因:沒有宣告自己的serialVersionUID,而使用系統的.在進行反序列化的時候,類被改動了,系統認為現在的類
 * 已經不是原來的類了(在使用系統的id進行識別的時候,重寫給Person設定了id),認為此類無效
 * 
 * 3.使用系統的serialVersionUID與自定義的ID的區別?
 * 使用系統的,序列化和反序列化,id不能手動設定,使用的是編譯器預設生成的,一旦類發生了改動,id會重新賦值
 * 使用自定義的,序列化和反序列化,id不會發生改變,所以當反序列化的時候,即使對Person類進行了一些改動,也能繼續反序列化
 * 
 * 4.總結序列化,反序列化工程的注意點:
 * a.合理使用序列化流和反序列化流,要與輸入流與輸出流配合使用
 * b.進行序列化的類一定要實現Serializable介面,只要實現了介面就可以序列化.包括集合,包裝類等
 * c.進行序列化的類要保證當前類與內部的類都要實現Serializable介面
 * 
 */
public class Demo11 {
     public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
    	 //序列化
    	 fun1();
		 //逆序列化
    	 fun2();
	}
     
     //序列化
     public static void fun1() throws FileNotFoundException, IOException{
    	 //建立序列化流並關聯檔案
 		ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("temp4.txt"));
 		//實現序列化
 		//注意:序列化後得到的內容不能直接檢視,要看必須經過逆序列化
 		objectOutputStream.writeObject(new Person("bingbing",20));
 		//關閉流
 		objectOutputStream.close();
     }
     //逆序列化
     public static void fun2() throws FileNotFoundException, IOException, ClassNotFoundException {
    	//建立逆序列化流並關聯檔案
  		ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("temp4.txt"));
  		
  		//實現逆序列化--讀
  		Object object = objectInputStream.readObject();
  		Person person = (Person)object;
  		System.out.println(person);
  		
  		//關閉流
  		objectInputStream.close();
	}
}
//建立一個類
//這個類的物件要想進行序列化必須實現Serializable介面.
//類通過實現Serializable介面啟動序列化功能.未實現此介面的類無法實現序列化或逆序列化.
//如果沒有實現Serializable,會報異常NoSerializableException
//注意點:可序列化的物件的內部的元素也要都支援序列化.
class Person implements Serializable{
/**
 * generated:由編譯器自動生成的,後面加L表示long型資料
 * 
 *  */
	private static final long serialVersionUID = 9100147150931711124L;
	//	/**
//	 * default:預設的方式,可以由使用者自己指定,預設值是1L
//	 */
//	private static final long serialVersionUID = 17489587495847L;
	String name;
	int age;
	//int height;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Person() {
		super();
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", 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;
	}
}