1. 程式人生 > >Java序列化簡介及例子

Java序列化簡介及例子

Java序列化

簡介

  • Java序列化是指把Java物件轉換為位元組序列的過程;而Java反序列化是指把位元組序列恢復為Java物件的過程。

  • 為什麼需要序列化與反序列化 我們知道,當兩個程序進行遠端通訊時,可以相互發送各種型別的資料,包括文字、圖片、音訊、視訊等, 而這些資料都會以二進位制序列的形式在網路上傳送。那麼當兩個Java程序進行通訊時,能否實現程序間的物件傳送呢?答案是可以的。如何做到呢?這就需要Java序列化與反序列化了。換句話說,一方面,傳送方需要把這個Java物件轉換為位元組序列,然後在網路上傳送;另一方面,接收方需要從位元組序列中恢復出Java物件。

jdk裡面序列化api

ObjectInputStream

public class ObjectInputStreamextends InputStreamimplements ObjectInput, ObjectStreamConstants

ObjectInputStream 對使用 ObjectOutputStream 寫入的基本資料和物件進行反序列化。 只有支援 java.io.Serializable 或 java.io.Externalizable 介面的物件才能從流讀取。

readObject 方法用於從流讀取物件。應該使用 Java 的安全強制轉換來獲取所需的型別。在 Java 中,字串和陣列都是物件,所以在序列化期間將其視為物件。讀取時,需要將其強制轉換為期望的型別。

例如,要從由 ObjectOutputStream 中的示例寫入的流讀取:

FileInputStream fis = new FileInputStream("t.tmp");
        ObjectInputStream ois = new ObjectInputStream(fis);

        int i = ois.readInt();
        String today = (String) ois.readObject();
        Date date = (Date) ois.readObject();

        ois.close();

構造方法:

ObjectInputStream
public ObjectInputStream(InputStream in)
                  throws IOException建立從指定 InputStream 讀取的 ObjectInputStream。從流讀取序列化頭部並予以驗證。在對應的 ObjectOutputStream 寫入並重新整理頭部之前,此構造方法將阻塞。 
如果安裝了安全管理器,則重寫 ObjectInputStream.readFields 或 ObjectInputStream.readUnshared 方法的子類的構造方法直接或間接呼叫此構造方法時,它將對 "enableSubclassImplementation" SerializablePermission 進行檢查。 


引數:
in - 要從中讀取的輸入流 
丟擲: 
StreamCorruptedException - 如果流的頭部不正確 
IOException - 如果讀取流頭部時發生 I/O 錯誤 
SecurityException - 如果不受信任的子類非法重寫安全敏感的方法 
NullPointerException - 如果 in 為 null
另請參見:
ObjectInputStream(), readFields(), ObjectOutputStream.ObjectOutputStream(OutputStream)

ObjectOutputStream

public class ObjectOutputStreamextends OutputStreamimplements ObjectOutput, ObjectStreamConstants

ObjectOutputStream 將 Java 物件的基本資料型別和圖形寫入 OutputStream。可以使用 ObjectInputStream 讀取(重構)物件。通過在流中使用檔案可以實現物件的持久儲存。如果流是網路套接字流,則可以在另一臺主機上或另一個程序中重構物件。

只能將支援 java.io.Serializable 介面的物件寫入流中。每個 serializable 物件的類都被編碼,編碼內容包括類名和類簽名、物件的欄位值和陣列值,以及從初始物件中引用的其他所有物件的閉包。

例如,要寫入可通過 ObjectInputStream 中的示例讀取的物件,請執行以下操作:

FileOutputStream fos = new FileOutputStream("t.tmp");
        ObjectOutputStream oos = new ObjectOutputStream(fos);

        oos.writeInt(12345);
        oos.writeObject("Today");
        oos.writeObject(new Date());

        oos.close();

構造方法:

ObjectOutputStream
public ObjectOutputStream(OutputStream out)
                   throws IOException建立寫入指定 OutputStream 的 ObjectOutputStream。此構造方法將序列化流部分寫入底層流;呼叫者可以通過立即重新整理流,確保在讀取頭部時,用於接收 ObjectInputStreams 構造方法不會阻塞。 
如果安裝了安全管理器,則在通過重寫 ObjectOutputStream.putFields 或 ObjectOutputStream.writeUnshared 方法的子類的構造方法來直接或間接呼叫此構造方法時,它將對 "enableSubclassImplementation" SerializablePermission 進行檢查。 


引數:
out - 要寫入資料的輸出流 
丟擲: 
IOException - 如果在寫入流部分時發生 I/O 錯誤 
SecurityException - 如果不受信任的子類非法重寫安全敏感方法 
NullPointerException - 如果 out 為 null

序列化步驟

  • 一:建立一個物件輸出流,它可以包裝一個其它型別的目標輸出流
  • 二:通過物件輸出流的writeObject()方法寫物件

反序列化步驟

  • 一:建立一個物件輸入流,它可以包裝一個其它型別輸入流
  • 二:通過物件輸出流的readObject()方法讀取物件

簡單例項: 先定義一個學生類:

public class Student implements Serializable{
	
	 private String name;  
	 private char sex;  
	 private int year;  
	 private double gpa;
	 public Student(String name,char sex,int year,double gpa) {
		 	this.gpa = gpa;
		 	this.name = name;
		 	this.sex = sex;
		 	this.year = year;
	}
	 
	 
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public char getSex() {
		return sex;
	}
	public void setSex(char sex) {
		this.sex = sex;
	}
	public int getYear() {
		return year;
	}
	public void setYear(int year) {
		this.year = year;
	}
	public double getGpa() {
		return gpa;
	}
	public void setGpa(double gpa) {
		this.gpa = gpa;
	}  
	 
	 
	
}

再把學生類序列化到txt檔案中,並且反序列化讀取出來,輸出在控制檯:

public class UseStudent {
	public static void main(String[] args) throws IOException, ClassNotFoundException  {
		Student student = new Student("LIN",'a',2015, 12);
		File file = new File("student.txt");
		file.createNewFile();
		FileOutputStream fileOutputStream = new FileOutputStream(file);
		ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
		objectOutputStream.writeObject(student);
		objectOutputStream.flush();
		objectOutputStream.close();
		fileOutputStream.close();
		
		FileInputStream fileInputStream = new FileInputStream(file);
		ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
		Student student1  = (Student) objectInputStream.readObject();
		System.out.println(student1.getName());
		System.out.println(student1.getSex());
		System.out.println(student1.getYear());
		System.out.println(student1.getGpa());
		objectInputStream.close();
		fileInputStream.close();
	}
	
	

}