Java语言之对象序列化流、反序列化流

一,概述

1,对象的序列化:把对象以流的方式写入到文件中保存,即写对象,对象不仅包含字符,也有字节,使用字节流ObjectOutputStream。
2,对象的反序列化:把文件中保存的对象,以流的方式读取出来,读取的文件保存的都是字节,使用字节流ObjectInputStream。

二,ObjectOutputStream

java.io.ObjectOutputStream extends OutputStream.
OutputStream:对象的序列化流。
作用:把对象以流的方式写入到文件中保存

构造方法
ObjectOutputStream(OutputStream out):创建写入指定OutputStream的ObjectOutputStream。
参数
OutputStream out:字节输出流。

特有的成员方法
void writeObject(Object obj):将指定的对象写入ObjectOutputStream。

注意
序列化或者反序列化时,抛出NotSerializableException没有序列化异常。
类通过实现java.io.Serializable接口启用序列化功能,未实现该接口的类无法进行序列化和反序列化。
Serializable接口也叫做标记型接口,相当于给类添加了一个标记,当进行序列化和反序列化时,会检测该类是否有该接口:
有,可进行序列化和反序列化;
没有,抛出NotSerializableException异常。

public class Person implements Serializable{
......
}

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class DemoObjectOutputStream {
    public static void main(String[] args) throws IOException {
        FileOutputStream fos = new FileOutputStream("src\\Month_05\\day5_21\\Person.txt");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(new Person("小海",25));
        oos.close();
    }
}

transient 关键字:如果有一个属性不需要可序列化的,则该属性必须注明是瞬态的,用transient修饰。例如:
private transient int age;打印时打印默认值0。

三,ObjectInputStream

java.io.ObjectInputStream extends InputStream.
ObjectInputStream:对象的反序列化流。
作用:把文件中保存的对象,以流的方式读取出来使用。
构造方法
ObjectInputStream(InputStream in)
参数
InputStream in:字节输入流。
特有的成员方法
Object readObject():从ObjectInputStream中读取对象。该方法声明抛出ClassNotFoundException(class文件找不到异常),当不存在对象的class文件(即Person类不存在)时抛出此异常。

反序列化的前提
1,类必须实现Serializable接口;
2,必须存在类对应的class文件。

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;


public class DemoObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        FileInputStream fis = new FileInputStream("src\\Month_05\\day5_21\\Person.txt");
        ObjectInputStream ois = new ObjectInputStream(fis);
        Object o = ois.readObject();
        ois.close();
        Person p = (Person)o;
        System.out.println(p.getName()+","+p.getAge());//小海,25
    }
}

注意: InvalidClassException 异常,当JVM反序列化对象时,能找到class文件,但是class文件在序列化对象之后发生了修改(修改Person类),由于序列号不一致,那么反序列化操作也会失败,抛出一个 InvalidClassException 异常。
序列号冲突异常原理图:
在这里插入图片描述
解决方法
可在类当中加入序列版本号,如
private static final long serialVersionUID = 1L;

四,综合案例:序列化集合
import java.io.*;
import java.util.ArrayList;

public class DemoListSerial {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("小海",21));
        list.add(new Person("小军",29));
        list.add(new Person("小红",20));
        list.add(new Person("小凯",21));
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\Month_05\\day5_21\\list.txt"));
        oos.writeObject(list);
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\Month_05\\day5_21\\list.txt"));
        Object o = ois.readObject();
        ArrayList<Person> list2 = (ArrayList<Person>)o;
        for (Person p : list2) {
            System.out.println(p);
        }
        ois.close();
        oos.close();
        /*
        Person{name='小海', age=21}
        Person{name='小军', age=29}
        Person{name='小红', age=20}
        Person{name='小凯', age=21}
         */
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值