java中io流(二)
阿新 • • 發佈:2018-12-04
序列化與反序列化:
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異常
- 如果物件已經被序列化,則程式直接輸出一個序列化編號,而不再重新序列化。