Java IO详解(六)------序列化与反序列化(对象流)

1、什么是序列化与反序列化?

  序列化:指把堆内存中的 Java 对象数据,通过某种方式把对象存储到磁盘文件中或者传递给其他网络节点(在网络上传输)。这个过程称为序列化。通俗来说就是将数据结构或对象转换成二进制串的过程

  反序列化:把磁盘文件中的对象数据或者把网络节点上的对象数据,恢复成Java对象模型的过程。也就是将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程

 

2、为什么要做序列化?

  ①、在分布式系统中,此时需要把对象在网络上传输,就得把对象数据转换为二进制形式,需要共享的数据的 JavaBean 对象,都得做序列化。

  ②、服务器钝化:如果服务器发现某些对象好久没活动了,那么服务器就会把这些内存中的对象持久化在本地磁盘文件中(Java对象转换为二进制文件);如果服务器发现某些对象需要活动时,先去内存中寻找,找不到再去磁盘文件中反序列化我们的对象数据,恢复成 Java 对象。这样能节省服务器内存。

 

3、Java 怎么进行序列化?

  ①、需要做序列化的对象的类,必须实现序列化接口:Java.lang.Serializable 接口(这是一个标志接口,没有任何抽象方法),Java 中大多数类都实现了该接口,比如:String,Integer

  ②、底层会判断,如果当前对象是 Serializable 的实例,才允许做序列化,Java对象 instanceof Serializable 来判断。

  ③、在 Java 中使用对象流来完成序列化和反序列化

    ObjectOutputStream:通过 writeObject()方法做序列化操作

    ObjectInputStream:通过 readObject() 方法做反序列化操作

 

 第一步:创建一个 JavaBean 对象

新建的 Person 对象实现 Serializable 接口

package streamobj;

import java.io.Serializable;

/***
 * @ClassName: Person
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/11
 * @version : V1.0
 */
public class Person implements Serializable {
    //在 JavaBean 对象中增加一个 serialVersionUID 字段,用来固定这个版本,无论我们怎么修改,版本都是一致的,就能进行反序列化了
    private static final long serialVersionUID = 8656128222714547171L;

    private String name;
    transient private String password;//不需要序列化,用 transient 修饰
    private int age;

    public String getName() {
        return name;
    }

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

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

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

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

    public Person(String name, String password, int age) {
        super();
        this.name = name;
        this.password = password;
        this.age = age;
    }
}

 

 第二步:使用 ObjectOutputStream 对象实现序列化

package streamobj;

import java.io.*;

/***
 * @ClassName: PersonDemo
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/11
 * @version : V1.0
 */
public class PersonDemo {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        //在根目录下新建一个 io 的文件夹
        OutputStream op = new FileOutputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt");
        ObjectOutputStream ops = new ObjectOutputStream(op);

        ops.writeObject(new Person("xiaotao","value",18));

        ops.close();
        System.out.println("使用 ObjectOutputStream 对象实现序列化");
    }
}

 

第三步:使用ObjectInputStream 对象实现反序列化

反序列化的对象必须要提供该对象的字节码文件.class

package streamobj;

import java.io.*;

/***
 * @ClassName: PersonDemo2
 * @Description: TODO
 * @Auther: chujiu
 * @Date: 2020/6/11
 * @version : V1.0
 */
public class PersonDemo2 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {

        InputStream in = new FileInputStream("G:" + File.separator + "javabased" + File.separator + "JavaTest" + File.separator + "a.txt");
        ObjectInputStream os = new ObjectInputStream(in);

        Person p = (Person) os.readObject();
        System.out.println(p);  //Person{name='xiaotao', password='null', age=18}

        os.close();
        System.out.println("使用ObjectInputStream 对象实现反序列化");
    }
}

 

参考文章:https://www.cnblogs.com/ysocean/tag/Java%20IO%E8%AF%A6%E8%A7%A3%E7%B3%BB%E5%88%97/

posted @ 2020-06-11 11:17  杵臼  阅读(140)  评论(0编辑  收藏  举报