序列化与反序列化

为了了解序列化我们先从序列化的过程入手,从而类比来理解其概念。

序列化的过程分为以下几个阶段:

  1. 序列化:对象通过序列化器转换为字节流;

  2. 存储/传输:字节流被写入文件、数据库或通过网络发送;

  3. 反序列化:字节流被反序列化器读取并转换回对象。

为了更形象更简单地理解这几个概念,阿伟为大家类比了生活中的一个实例:

场景:在美好的未来中的某一天,你正在制作一个三明治,这个三明治包含了多种食材,比如面包、火腿、生菜、奶酪和番茄。现在,你的朋友在另一个城市,他也想制作一个一模一样的三明治,但是他没有你这里的食材。

序列化的过程就像是你把三明治的制作信息写在一张纸上,这张纸包含了所有制作三明治所需的信息:

  • 2片面包

  • 3片火腿

  • 2片生菜

  • 1片奶酪

  • 2片番茄

这张纸就是序列化后的数据,它包含了创建一个三明治所需的所有信息,但是它是以一种可以轻松传输和存储的格式存在的。

存储的过程就像是你把这张纸放在一个信封里,然后把它保存在抽屉里。这样,即使过了一段时间,你也能根据这张纸重新制作三明治。

传输的过程就像是你把这张纸放在另一个信封里,通过邮件发送给你的朋友。你的朋友收到信封后,可以根据里面的信息在当地购买相应的食材。

反序列化的过程就像是你的朋友收到信封,根据里面的信息在当地购买食材,然后按照纸上的指示制作三明治。最终,他成功地制作出了一个和你这里一模一样的三明治。

在这个例子中,三明治就是你的对象,那张纸就是序列化后的数据,保存和传输的过程就是序列化数据的存储和传输,而你朋友根据纸上的信息制作三明治的过程就是反序列化。

理解了概念之后,就该思考那为什么要进行序列化呢?序列化又有什么好处呢?

1.数据持久化

  • 保存状态:通过序列化,我们可以将程序的状态保存下来,以便在程序关闭后再次启动时恢复到之前的状态。

  • 跨平台存储:序列化的数据可以存储在多种类型的存储介质上,如硬盘、光盘、USB驱动器等。

2.网络通信

  • 远程调用:在分布式系统中,序列化允许对象在网络上传输,使得远程计算机可以接收这些对象并执行相应的操作。

  • 数据交换:不同的系统或服务之间可以通过序列化来交换数据,如通过HTTP请求发送JSON或XML格式的数据。

3.内存管理

  • 优化内存使用:在某些情况下,序列化可以用于优化内存使用,例如,通过序列化对象到磁盘来减少内存中活跃对象的数量。若一直放在内存当中,会增大内存的消耗。

了解了以上内容,就该去实践一下啦,今天举例一下“数据持久化”的使用场景:

import java.io.*;

public class DataPersistenceExample {

public static void main(String[] args) {
    try {
        // 创建对象
        MyObject obj = new MyObject("awei", 18);
​
        // 序列化对象到文件
        FileOutputStream fileOut = new FileOutputStream("myObject.ser");
        ObjectOutputStream out = new ObjectOutputStream(fileOut);
        out.writeObject(obj);
        out.close();
        fileOut.close();
​
        // 从文件反序列化对象
        FileInputStream fileIn = new FileInputStream("myObject.ser");
        ObjectInputStream in = new ObjectInputStream(fileIn);
        MyObject deserializedObj = (MyObject) in.readObject();
        in.close();
        fileIn.close();
​
        // 输出反序列化对象的信息
        System.out.println("Name: " + deserializedObj.name);
        System.out.println("Age: " + deserializedObj.age);
    } catch (IOException | ClassNotFoundException e) {
        e.printStackTrace();
    }
}
​
static class MyObject implements Serializable {
    private static final long serialVersionUID = 1L;
    String name;
    int age;
​
    MyObject(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
}

上述代码解析:

  1. FileOutputStream fileOut = new FileOutputStream("myObject.ser");:创建一个FileOutputStream对象,用于将数据写入名为"myObject.ser"的文件。

  2. ObjectOutputStream out = new ObjectOutputStream(fileOut);:创建一个ObjectOutputStream对象,它包装了FileOutputStream,用于将对象序列化到文件。

  3. out.writeObject(obj);:将MyObject对象写入文件。

  4. out.close();:关闭ObjectOutputStream

  5. fileOut.close();:关闭FileOutputStream

  6. FileInputStream fileIn = new FileInputStream("myObject.ser");:创建一个FileInputStream对象,用于从名为"myObject.ser"的文件中读取数据。

  7. ObjectInputStream in = new ObjectInputStream(fileIn);:创建一个ObjectInputStream对象,它包装了FileInputStream,用于从文件中反序列化对象。

  8. MyObject deserializedObj = (MyObject) in.readObject();:从文件中读取对象,并将其转换为MyObject类型。

  9. in.close();:关闭ObjectInputStream

  10. fileIn.close();:关闭FileInputStream

  11. System.out.println("Name: " + deserializedObj.name);:打印反序列化对象的name属性。

  12. System.out.println("Age: " + deserializedObj.age);:打印反序列化对象的age属性。

  13. private static final long serialVersionUID = 1L;:定义一个serialVersionUID字段,它是序列化对象的唯一标识符。

序列化时,数据传递的流程是:

1.从内存中的对象(obj)到ObjectOutputStream(out)。
2.然后通过ObjectOutputStream写入到FileOutputStream(fileOut)。
3.最后,FileOutputStream将数据写入到文件系统上的文件("myObject.ser")。

序列化是将对象的状态信息转换为可以存储或传输的形式的过程,而反序列化则是相反的过程。在这个例子中,MyObject对象被序列化到一个名为"myObject.ser"的文件中,然后从该文件中反序列化回来,并打印出对象的属性。

结束~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值