序列化与反序列化

序列化与反序列化

概述

序列化: 就是使用流的技术将对象中的数据保存到文件中。
反序列化: 就是使用流的技术将文件中的数据读取到对象中。

使用到的流技术

序列化:ObjectOutputStream
反序列化:ObjectInputStream

ObjectOutputStream介绍 (序列化)

构造:
ObjectOutputStream(OutputStream out)
参数可以传入这两个:FileOutputStream,BufferedOutputStream

关键方法:
writeObject(Object obj) 将指定的对象写入文件。

使用前提:
被写入对象所属的类必须要实现 Serializable 接口。

注意: 建议添加
给该类指定的序列化号,是为了防止序列化后,改动代码所带来的问题,
所以我们指定一个固定的序列化号,使得每次序列化的编号都是固定的,这样就能解决一系列的问题。
public static final long serialVersionUID = 42L;

如果不想序列化某个字段的话,可以在该字段上加上:transient 关键字。
使用格式:修饰符 transient 数据类型 变量名;

ObjectOutputStream演示

public class Student implements Serializable {
    //给定序列号防止改动带来的问题
    public static final long serialVersionUID = 42L;

    private String name;
    private String sex;
    private Integer age;

    public Student() {
    }

    public Student(String name, String sex, Integer age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }
}


测试类:
public class Demo{
    public static void main(String[] args) {
        Student s = new Student("迪丽热巴", "女", 20);
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\a.txt"))){
            oos.writeObject(s);
        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

存储到文件中的结果:虽然我们看不懂但是这是正确的,不用担心。我们在反序列化后就能够看懂了。

�� sr cn.itheima.Work3.StudentC ϖo�Y� L aget Ljava/lang/Integer;L namet L
java/lang/String;L sexq ~ xpsr java.lang.Integer⠤���8 I valuexr j
ava.lang.Number������  xp   t 迪丽热巴t 女

ObjectInputStream介绍 (反序列化)

构造:
ObjectInputStream(InputStream in)
参数可以传入这两个:FileInputStream,BufferedInputStream

关键方法:
Object readObject() 将指定文件的内容读取到对象中。

使用前提:
被写入对象所属的类必须要实现 Serializable 接口。

注意:
反序列化操作的文件一定是序列化时操作的文件。

ObjectInputStream演示

public class Demo{
    public static void main(String[] args) {
        try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D:\\a.txt"))){
            Student stu = (Student) ois.readObject();
            System.out.println(stu);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

输出结果:可以看到经过序列化以后,保存到Student对象中,就能够看懂了。

Student{name='迪丽热巴', sex='女', age=20}

拓展

需求:同时序列化多个Student对象和同时反序列化多个Student对象

如果单纯的使用死循环进行反序列化,会出现 EOFException (文件异常到达结尾)异常。
如果不知道文件中有多少个对象,可以使用序列化集合的方式来进行操作。

/*
    如果有不想被序列化的字段可以加上这个transient关键字
    使用格式:修饰符 transient 数据类型 变量名;
 */
public class Person implements Serializable {
    //给定序列号防止改动代码带来的问题 (后面的值可以任意写)
    public static final long serialVersionUID = 40L;
    
    private String name;
    private Integer age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}


测试类:
public class Demo{
    public static void main(String[] args) {
        //writerObjectDemo();
        readerObjectDemo();
    }

    /**
     * 演示:反序列化 将文件中的数据存储到Person对象中
     * 需要使用的类:ObjectInputStream
     * 方法:readObject
     */
    private static void readerObjectDemo() {
        try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream("G:\\writerPerson.txt"))){

            ArrayList<Person> list = (ArrayList<Person>) ois.readObject();

            for (Person p : list){
                System.out.println(p);
            }

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 演示:序列化 将Person对象存入文件中
     * 需要使用的类:ObjectOutputStream
     * 方法:writeObject
     */
    private static void writerObjectDemo() {
        try(ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("G:\\writerPerson.txt"))){
            ArrayList<Person> list = new ArrayList<>();
            list.add(new Person("张三",18));
            list.add(new Person("猪皮",20));
            list.add(new Person("丽斯",20));

            oos.writeObject(list);

        }catch (IOException e){
            e.printStackTrace();
        }
    }
}

结果:

Person{name='张三', age=18}
Person{name='猪皮', age=20}
Person{name='丽斯', age=20}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值