国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Java從零開始學三十九(對象序列化)

2019-11-14 23:08:07
字體:
來源:轉載
供稿:網友
java從零開始學三十九(對象序列化)一、序列化

將對象的狀態存儲到特定存儲介質中的過程

對象序列化,就是把一個對象變為二進制的數據流的一種方法,通過對象序列化可以方便的實現對象的傳輸或存儲。序列化保存對象的“全景圖”,構建對象的“全景天窗”.如果一個類的對象想被序列化,則對象所在的類必須實現java.io.Serializable接口二、對象的序列化和反序列化要想完成對象的輸入或輸出,還必須依靠對象輸出流(ObjectOutputStream)和對象輸入流(ObjectInputStream)使用對象輸出流輸出序列化對象的步驟,有時也稱為序列化,而使用對象輸入流讀入對象的過程,有時也稱為反序列化序列化步驟:
  1. 創建一個對象輸出流ObjectOutputStream
  2. writeObject()方法輸出序列化對象

反序列化步驟:

  1. 創建一個對象輸入流ObjectInputStream
  2. readObject()方法讀取流中的對象
三、對象輸出流(ObjectOutputStream)和對象輸入流(ObjectInputStream)3.1、對象輸出流:ObjectOutputStream
No.方法或常量類型描述
1public ObjectOutputStream(OutputStream out) throws IOException構造傳入輸出的對象
2public final void writeObject(Object obj) throws IOException普通輸出對象
此類的使用形式與PRintStream非常的相似,在實例化時也需要傳入一個OutputStream的子類對象,之后根據傳入的OutputStream子類的對象不同,輸出的位置也不同。3.2、對象輸入流:ObjectInputStream
No.方法或常量類型描述
1public ObjectInputStream(InputStream in) throws IOException構造構造輸入對象
2public final Object readObject() throws IOException, ClassNotFoundException普通從指定位置讀取對象
此類也是InputStream的子類,與PrintStream類的使用類似,此類同樣需要接收InputStream類的實例才可以實例化四、transient關鍵字當使用Serializable接口實現序列化操作時,如果一個對象中的某個屬性不希望被序列化的話,則可以使用transient關鍵字進行聲明
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;    }}
五、實現反序列化注意事項
  • 反序列化過程無需要使用構造器生成對象
  • 按順序反序列化恢復對象
  • 父類Serializable或者存在無參數構造方法
六、例子
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、序列化算法
  • 對象分配序列號
  • 當程序試圖序列化一個對象時,將會檢查是否已經被序列化,只有序列化后的對象才能被轉換成字節序列輸出
  • 如果對象已經被序列化,則程序直接輸出一個序列化編號,而不在重新序列化
7.2、序列化機制

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===========反序列化完成=========張老師和韓老師教的是同一個學生


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 绥德县| 盱眙县| 双鸭山市| 兴和县| 陈巴尔虎旗| 乐业县| 卓资县| 临沂市| 茌平县| 贵定县| 维西| 九龙县| 岳西县| 安达市| 阿坝| 邵阳市| 九龙城区| 平乐县| 三江| 安徽省| 嘉黎县| 镶黄旗| 开原市| 桦川县| 永嘉县| 通榆县| 万荣县| 金山区| 桃园县| 色达县| 岳西县| 崇文区| 盈江县| 连城县| 靖远县| 衢州市| 乐昌市| 泸水县| 衡山县| 桦南县| 华亭县|