將對象的狀態存儲到特定存儲介質中的過程
對象序列化,就是把一個對象變為二進制的數據流的一種方法,通過對象序列化可以方便的實現對象的傳輸或存儲。
序列化保存對象的“全景圖”,構建對象的“全景天窗”.如果一個類的對象想被序列化,則對象所在的類必須實現java.io.Serializable接口二、對象的序列化和反序列化要想完成對象的輸入或輸出,還必須依靠對象輸出流(ObjectOutputStream)和對象輸入流(ObjectInputStream)使用對象輸出流輸出序列化對象的步驟,有時也稱為序列化,而使用對象輸入流讀入對象的過程,有時也稱為反序列化
序列化步驟:反序列化步驟:
| No. | 方法或常量 | 類型 | 描述 |
| 1 | public ObjectOutputStream(OutputStream out) throws IOException | 構造 | 傳入輸出的對象 |
| 2 | public final void writeObject(Object obj) throws IOException | 普通 | 輸出對象 |
| No. | 方法或常量 | 類型 | 描述 |
| 1 | public ObjectInputStream(InputStream in) throws IOException | 構造 | 構造輸入對象 |
| 2 | public final Object readObject() throws IOException, ClassNotFoundException | 普通 | 從指定位置讀取對象 |
import java.io.Serializable;public class Person implements Serializable { // 此類的對象可以被序列化 private transient String name; // 此屬性將不被序列化 private int age; // 此屬性將被序列化 public Person(String name, int age) { this.name = name; this.age = age; } public String toString() { // 覆蓋toString(),輸出信息 return "姓名:" + this.name + ";年齡:" + this.age; }}五、實現反序列化注意事項package com.pb.serializable;import java.io.Serializable;/* * 學生類 并實現接口Serializable接口,使用之可以序列化 *//* * 序列化 * 1.創建一個對象,這個對象將被序列化,并寫入文件中,前提是這個類實現了Serializable接口 * 2.實例化ObjectOutputStream的對象 * 3.調用ObjectOutputStream的writerObject()方法,將對象寫入流中 * 4.關閉流 * transient關鍵字 * 可以保護對象中的敏感信息不被寫入到文件中 * 反序列化 * 1.實例化ObjectInputStream對象 * 2.調用ObjectInputStream的readObject()方法,獲取對象時,要進行強制類型轉換 * 3.關閉流 */public class Student implements Serializable { private String name; // 姓名 private int age; // 年齡 private String gender; // 性別 private transient String passWord; // 密碼屬性不能被序列化 // 構造方法 public Student() { // 無參 } // 有參數 public Student(String name, int age, String gender, String password) { this.name = name; this.age = age; this.gender = gender; this.password = password; } //getter、setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { if(age>0&&age<150) this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { if(gender.equals("男") || gender.equals("女")) this.gender = gender; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } // 自我介紹 public void say() { System.out.println("姓名:" + this.name + "/t年齡:" + this.age + "/t性別:" + this.gender+"/t密碼 : "+this.password); }}序列化:
package com.pb.serializable;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectOutputStream;import java.util.ArrayList;import java.util.List;/* * 序列化 * 1.創建一個對象,這個對象將被序列化,并寫入文件中,前提是這個類實現了Serializable接口 * 2.實例化ObjectOutputStream的對象 * 3.調用ObjectOutputStream的writerObject()方法,將對象寫入流中 * 4.關閉流 * transient關鍵字 * 可以保護對象中的敏感信息不被寫入到文件中 */public class SerializableObj { public static void main(String[] args) { try { //1.聲明一個文件輸出流 FileOutputStream fos = new FileOutputStream("d:/test/obj.txt"); //2.聲明ObjectOutputStream流對象 ObjectOutputStream oos=new ObjectOutputStream(fos); //也可以2步合一步 //ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:/test/obj.txt")); Student stu1=new Student("張三", 23, "男", "123456"); Student stu2=new Student("李四", 24, "女", "123123"); Student stu3=new Student("王五", 25, "男", "123321"); Student stu4=new Student("趙六", 26, "男", "999999"); //創建集合并添加 List<Student> list=new ArrayList<Student>(); list.add(stu1); list.add(stu2); list.add(stu3); list.add(stu4); //3.將student對象序列化,寫入輸出oos流 oos.writeObject(stu1); oos.writeObject(stu2); oos.writeObject(stu3); oos.writeObject(stu4); oos.writeObject(list); //4.關閉流 oos.close(); fos.close(); System.out.println("=======序列化完成======"); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }}反序列化:
package com.pb.serializable;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.util.List;/* * 反序列化 * 1.實例化ObjectInputStream對象 * 2.調用ObjectInputStream的readObject()方法,獲取對象時,要進行強制類型轉換 * 3.關閉流 */public class ReadSerializableObj { public static void main(String[] args) { try { //1.聲明一個文件輸出流 FileInputStream fis = new FileInputStream("d:/test/obj.txt"); //2.實例化ObjectInputStream ObjectInputStream ois=new ObjectInputStream(fis); //也可以全2為一 //ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/test/obj.txt")); //3.聲明一個Student對象和集合 System.out.println("=====反序列化學生對象======="); Student stu1= (Student) ois.readObject(); stu1.say(); Student stu2= (Student) ois.readObject(); stu2.say(); Student stu3= (Student) ois.readObject(); stu3.say(); Student stu4= (Student) ois.readObject(); stu4.say(); System.out.println("=====反序列化集合對象======="); List<Student> list=(List<Student>) ois.readObject(); for (Student s : list) { s.say(); } //4.關閉流 ois.close(); fis.close(); System.out.println("====反序列完成===="); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}結果:
=====反序列化學生對象=======姓名:張三 年齡:23 性別:男 密碼 : null姓名:李四 年齡:24 性別:女 密碼 : null姓名:王五 年齡:25 性別:男 密碼 : null姓名:趙六 年齡:26 性別:男 密碼 : null=====反序列化集合對象=======姓名:張三 年齡:23 性別:男 密碼 : null姓名:李四 年齡:24 性別:女 密碼 : null姓名:王五 年齡:25 性別:男 密碼 : null姓名:趙六 年齡:26 性別:男 密碼 : null====反序列完成====
從結果中可以看到:password使用transient關鍵字后,沒有被序列化,反序列化中,讀出的是默認字段類型的默認值null
七、包含引用類型屬性的對象序列化引用類必須也為可序列化
public class Teacher implements Serializable { private String name; // 姓名 private int age; // 年齡 private String gender; // 性別 private transient String password; // 密碼屬性不能被序列化 private Student stu; //這里的Student類必須也是可以序列化的,}這里有個Teacher類,但屬性中有一個Student類的對象,這時Teacher要實現序列時,Student必須也要實現Serializable接口才可以
7.1、序列化算法Teacher類:
package com.pb.serializable;import java.io.Serializable;/* * 教師類實例Serializable接口 */public class Teacher implements Serializable { private String name; // 姓名 private int age; // 年齡 private String gender; // 性別 private transient String password; // 密碼屬性不能被序列化 private Student stu; //這里的Student類必須也是可以序列化的, //構造方法 public Teacher() { //無參數 } public Teacher(String name, int age, String gender, String password, Student stu) { //有參數 this.name = name; this.age = age; this.gender = gender; this.password = password; this.stu = stu; } //getter、setter方法 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; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Student getStu() { return stu; } public void setStu(Student stu) { this.stu = stu; } // 自我介紹 public void say() { System.out.println("姓名:" + this.name + "/t年齡:" + this.age + "/t性別:" + this.gender+"/t密碼 : "+this.password); } }序列化和化序列化類:
package com.pb.serializable;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;/* * 老師類的序列化和反序列化 2個老師引用同一個學生對象 */public class WriterTeacherObj { public static void main(String[] args) { /* * 序列化 * 1.序列化時時候,會查找當前對象的序列化編號是否存在,不存在,保存該對象 * 2.寫入操作時,當對象的序列化編號存在時候,會輸出一個當前對象的序列化編號,而不是當前對象 * 3.反序列化對象時, 程序會自動查找,當前對象的序列化編號,之后如果,發現當前的對象的序列化編號被其它對象引用時,則返回同一個對象 */ try { //1.實例化ObjectOutputStream ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("d:/test/teacher.txt")); //2.實例化老師對象 Student student=new Student("馬達", 23, "男", "123123"); //2個老師引用同一個學生對象 Teacher teacher_han=new Teacher("韓冰", 22, "女", "123456789", student); Teacher teacher_zhang=new Teacher("張三豐", 108, "男", "123456789", student); //3.對象序列 oos.writeObject(teacher_han); oos.writeObject(teacher_zhang); //4.關閉流 oos.close(); System.out.println("====================序列化完成================="); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } /* * 反序列化 */ System.out.println("==================開始反序列化================"); try { //1.實例化ObjectInputStream對象 ObjectInputStream ois=new ObjectInputStream(new FileInputStream("d:/test/teacher.txt")); //2.反序列聲明一個Teacher對象強制類型轉換 Teacher teacher_han=(Teacher) ois.readObject(); Teacher teacher_zhang=(Teacher) ois.readObject(); //3.輸入Teacher中的信息 System.out.println("==================老師信息================"); teacher_han.say(); teacher_zhang.say(); System.out.println("=================老師中學生信息============="); teacher_han.getStu().say(); teacher_zhang.getStu().say(); //4.關閉流 ois.close(); System.out.println("===========反序列化完成========="); //判斷2個老師的學生是否為同一個 if(teacher_han.getStu()==teacher_zhang.getStu()){ System.out.println("張老師和韓老師教的是同一個學生"); }else{ System.out.println("張老師和韓老師教的不是同一個學生"); } } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}結果:
====================序列化完成===================================開始反序列化==================================老師信息================姓名:韓冰 年齡:22 性別:女 密碼 : null姓名:張三豐 年齡:108 性別:男 密碼 : null=================老師中學生信息=============姓名:馬達 年齡:23 性別:男 密碼 : null姓名:馬達 年齡:23 性別:男 密碼 : null===========反序列化完成=========張老師和韓老師教的是同一個學生
新聞熱點
疑難解答