序列化与反序列化(ObjectOutputStream、ObjectInputStream)

序列化:

把对象以流的方式,写入到文件中保存,也叫对象的序列化
对象中包含的不仅仅是字符,所以要使用字节
ObjectOutputStream:对象的序列化流-->writeObject(对象)

反序列化:
把文件中保存的对象,以流的方式读取出来,叫做读对象,也叫对象的反序列化
读取的文件包存的都是字节,使用字节流 --->readObject();
接收时为对象 ,要用Object类来接收。

 

ObjectOutputStream类


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

构造方法:
public ObjectOutputStream(OutputStream out)

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

使用步骤:
1.创建ObjectOutputStream对象,构造方法中传递字节输出流对象
2.使用ObjectOutputStream对象中的方法writeObject,把对象写入到文件中
3.释放资源
注意:
序列化和反序列化的时候,会出现NotSerializableException没有序列化异常
要写的类对象必须实现java.io.Serializable接口以启动其序列化功能。为事项该序列化接口,将无法使其序列化与反序列化
Serializable接口也叫标记型接口(改接口里面什么都没有,只进行一个标记作用)
要进行序列化和反序列化的类必须实现java.io.Serializable接口,就会给类添加一个标记
当我们进行序列化和反序列化时,就检测是否有该标记
有:序列化或反序列化
没有:抛出NotSerializableException异常

package iotest.testObjectIO;

import java.io.Serializable;

class Person implements Serializable {//必须实现Serializable接口,否则会抛出NotSerializableException异常
    String name;// 被transient修饰的成员变量,不能被序列化,这儿如果加transient,读到的对象名为null

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

    public String getName() {
        return name;
    }

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

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

public class TestObjectOutputStream {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("src\\iotest\\testObjectIO\\a.txt"));
        Person person = new Person("小明");
        oos.writeObject(person);
        oos.close();

    }

}

 

ObjectInputStream类:


java.io.ObjectInputStream extends InputStream
ObjectInputStream:对象的反序列化流
作用:将文件中保存的对象以流的形式读取出来,从而进行使用
构造方法:
public ObjectInputStream(InputStream in)

特有的成员方法:

public final Object readObject():将文件中存储的对象读取出来,并返回Object对象(这儿可强转对象)

使用步骤:
1.创建ObjectInputStream对象,构造方法中传递字节输入流对象
2.使用ObjectInputStream对象中的方法readObject(),把文件中的对象读取出来
3.释放资源
4.使用读取出来的对象(可以使用将Object对象强转为具体的类对象)
反序列化的前提:
1.类必须实现Serializable
2.必须存在类的写入文件

package iotest.testObjectIO;

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

public class TestObjectInputStream {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois = new ObjectInputStream(new FileInputStream("src\\iotest\\testObjectIO\\a.txt"));
        Person person = (Person) ois.readObject();//将返回的Object对象强转为person对象
        System.out.println(person.getName());
        ois.close();
    }
}

 

transient关键字:瞬态关键字
被transient修饰的成员变量,不能被序列化


序列号冲突异常InvalidClassException(Serializable接口中)

 

 

练习:序列化集合

package iotest.testObjectIO;

import java.io.*;
import java.util.ArrayList;

//练习:序列化集合
//当我们在文件中存储多个对象,可以把文件存储到一个集合中,对集合进行序列化与反序列化
public class ObjectList {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ArrayList<Person> arrayList = new ArrayList<>();
        arrayList.add(new Person("小明"));
        arrayList.add(new Person("小红"));
        arrayList.add(new Person("李华"));
        arrayList.add(new Person("张三"));
        arrayList.add(new Person("李四"));

        ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("src\\iotest\\testObjectIO\\b.txt"));
        objectOutputStream.writeObject(arrayList);

        ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("src\\iotest\\testObjectIO\\b.txt"));
        ArrayList<Person> arrayList1 = (ArrayList<Person>) objectInputStream.readObject();
        for (Person person : arrayList1) {
            System.out.println(person.getName());
        }

        objectInputStream.close();
        objectOutputStream.close();
    }
}

 

posted @ 2020-08-01 22:53  DannyBoy~  阅读(331)  评论(0编辑  收藏  举报