滚雪球学Java(76):从零开始:Java对象序列化和反序列化的简明指南

举报
bug菌 发表于 2024/04/14 18:13:28 2024/04/14
【摘要】   咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!环境说明:Windows 10 +...

在这里插入图片描述

  咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~


🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!!

环境说明:Windows 10 + IntelliJ IDEA 2021.3.2 + Jdk 1.8

@[toc]

对象序列化和反序列化

前言

在软件开发中,数据的持久化和传输是一个非常重要的话题。当我们需要将对象保存到磁盘或通过网络传输时,就需要进行对象的序列化和反序列化操作。本文将以Java开发语言为例,介绍对象序列化和反序列化的概念、用法以及相关的优缺点分析。

摘要

对象序列化和反序列化是将对象转换为字节流并保存到磁盘或通过网络传输的过程,以及将字节流恢复为对象的过程。在Java中,我们可以使用java.io.Serializable接口实现对象的序列化和反序列化。

简介

对象序列化是将对象转换为字节流的过程。在Java中,被序列化的对象必须实现java.io.Serializable接口。该接口是一个标记接口,不包含任何方法。当一个对象被标记为可序列化后,它的所有非静态和非瞬态的字段都会被转换为字节流。

对象反序列化是将字节流转换为对象的过程。在Java中,可以通过java.io.ObjectInputStream类实现对象的反序列化。反序列化的过程将字节流逆向解析,将其转换为原来的对象。

源代码解析

以下是一个简单的Java对象的序列化和反序列化示例代码:

import java.io.*;

public class SerializationExample {
    public static void main(String[] args) {
        // 创建一个对象并设置值
        Person person = new Person("John", 30);

        // 将对象序列化到文件
        try {
            FileOutputStream fileOut = new FileOutputStream("person.ser");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(person);
            out.close();
            fileOut.close();
            System.out.println("对象已序列化到person.ser文件");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 将文件中的对象反序列化
        try {
            FileInputStream fileIn = new FileInputStream("person.ser");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Person serializedPerson = (Person) in.readObject();
            in.close();
            fileIn.close();

            System.out.println("反序列化得到的对象:");
            System.out.println("姓名:" + serializedPerson.getName());
            System.out.println("年龄:" + serializedPerson.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

class Person implements Serializable {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

代码分析:

  该代码使用Java的序列化和反序列化功能来将一个Person对象保存到文件和重新加载对象。

  在main方法中,首先创建一个Person对象并设置其属性值,然后使用FileOutputStream和ObjectOutputStream将该对象序列化到文件"person.ser"中。序列化过程中,程序会将对象的状态转换为字节流,并写入到文件中。

  接着,使用FileInputStream和ObjectInputStream从文件中读取字节流,并将其反序列化为一个Person对象。反序列化过程中,程序会将字节流转换为对象的状态,并重新构建该对象。

  最后,打印反序列化得到的Person对象的属性值。

  Person类实现了Serializable接口,这是一个标记接口,用于指示该类可以被序列化。该类有两个私有属性name和age,并提供了相应的访问方法。

  总结:该代码展示了Java中如何使用序列化和反序列化功能来保存和加载对象的状态。这种方法可以用于持久化对象,或在不同的系统间传递对象的状态。

应用场景案例

对象序列化和反序列化在实际应用中有多种用途。以下是一些常见的应用场景案例:

  1. 数据持久化:将对象保存到磁盘或数据库中,以便后续使用或恢复。
  2. 远程调用:在分布式系统中,可以将对象进行序列化后通过网络传输,实现远程调用。
  3. 缓存机制:将对象序列化后保存在缓存中,提高系统性能。
  4. 消息传递:在消息队列中,可以将对象序列化后发送给其他系统进行处理。

优缺点分析

对象序列化和反序列化具有以下优点:

  1. 简单易用:Java提供了内置的序列化机制,开发者只需实现java.io.Serializable接口即可。
  2. 可移植性:序列化后的字节流可以在不同平台和不同版本的Java虚拟机之间进行传输和恢复。
  3. 高效性:序列化后的字节流体积较小,可以节省存储空间和网络带宽。

然而,对象序列化和反序列化也存在一些缺点:

  1. 版本兼容性:当对象的类发生变化时,可能会导致反序列化失败或数据丢失。
  2. 安全性问题:序列化和反序列化的过程可能存在安全漏洞,需要注意对恶意对象进行检查。

类代码方法介绍

Person类是一个简单的示例,包含了nameage两个字段,以及对应的getter方法。

package com.demo.javase.day76;

import java.io.Serializable;

/**
 * @Author bug菌
 * @Date 2023-12-27 17:11
 */
public class Person implements Serializable {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

代码分析:

  根据上述代码分析,我们可以得出以下结论:

  1. 代码所在的包名为com.demo.javase.day76。

  2. 类名为Person。

  3. Person类实现了Serializable接口,表示该类可以被序列化。

  4. Person类有两个私有属性,分别为name和age。

  5. Person类有一个公共的构造方法,用于初始化name和age属性。

  6. Person类有两个公共的getter方法,分别用于获取name和age属性的值。

  总体来说,这段代码定义了一个可序列化的Person类,用于存储人员的姓名和年龄信息。

测试用例

测试代码

以下是一个简单的测试用例,使用main函数进行对象的序列化和反序列化:

package com.demo.javase.day76;

import java.io.*;

/**
 * @Author bug菌
 * @Date 2023-12-27 17:11
 */
public class SerializationExampleTest {

    public static void main(String[] args) {
        // 创建一个对象并设置值
        Person person = new Person("John", 30);

        // 将对象序列化到文件
        try {
            FileOutputStream fileOut = new FileOutputStream("./person.txt");
            ObjectOutputStream out = new ObjectOutputStream(fileOut);
            out.writeObject(person);
            out.close();
            fileOut.close();
            System.out.println("对象已序列化到person.txt文件");
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 将文件中的对象反序列化
        try {
            FileInputStream fileIn = new FileInputStream("./person.txt");
            ObjectInputStream in = new ObjectInputStream(fileIn);
            Person serializedPerson = (Person) in.readObject();
            in.close();
            fileIn.close();

            System.out.println("反序列化得到的对象:");
            System.out.println("姓名:" + serializedPerson.getName());
            System.out.println("年龄:" + serializedPerson.getAge());
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

测试代码分析

  根据如上测试用例,在此我给大家进行深入详细的解读一下测试代码,以便于更多的同学能够理解并加深印象。

  该代码演示了Java中对象的序列化和反序列化操作。

  首先,在main方法中创建了一个Person对象,并设置了其姓名为"John",年龄为30。

  然后,通过FileOutputStream和ObjectOutputStream将该Person对象序列化到文件person.txt中。因为ObjectOutputStream可以直接将对象写入到输出流中,所以可以直接调用writeObject方法将person对象写入到out流中。

  接着,通过FileInputStream和ObjectInputStream将文件person.txt中的对象进行反序列化。同样,因为ObjectInputStream可以直接从输入流中读取对象,所以可以直接调用readObject方法将文件中的对象读取到serializedPerson变量中。

  最后,打印出反序列化得到的对象的姓名和年龄。

  需要注意的是,序列化和反序列化的过程中可能会抛出IOException和ClassNotFoundException异常,需要进行异常处理。

测试结果

  根据如上的测试用例,作者在本地进行测试结果如下,仅供参考,你们也可以自行修改测试用例或者添加其他的测试数据或测试方法,以便于进行熟练学习以此加深知识点的理解。

在这里插入图片描述

附上person.txt文件存放位置。

在这里插入图片描述

全文小结

  本文介绍了对象序列化和反序列化的概念、用法以及相关的优缺点分析。通过Java的java.io.Serializable接口和java.io.ObjectInputStream类,我们可以方便地实现对象的序列化和反序列化操作。对象序列化和反序列化在数据持久化、远程调用、缓存机制和消息传递等场景中发挥重要作用。

总结

  通过本文的介绍,我们了解了对象序列化和反序列化的基本原理和用法,并分析了其优缺点。在实际应用中,我们可以根据具体需求选择合适的序列化方式,保证数据的正确传输和恢复。对象序列化和反序列化是Java开发中一个重要的技术,掌握好相关知识对于提高软件开发效率和性能具有重要意义。

  … …

  好啦,这期的内容就基本接近尾声啦,若你想学习更多,你可以看看专栏的导读篇《「滚雪球学Java」教程导航帖》,本专栏致力打造最硬核 Java 零基础系列学习内容,🚀打造全网精品硬核专栏,带你直线超车;欢迎大家订阅持续学习。功不唐捐,久久为功!

「赠人玫瑰,手留余香」,咱们下期拜拜~~

附录源码

  如上涉及所有源码均已上传同步在「Gitee」,提供给同学们一对一参考学习,辅助你更迅速的掌握。

☀️建议/推荐你

  无论你是计算机专业的学生,还是对编程感兴趣的跨专业小白,都建议直接入手「滚雪球学Java」专栏;该专栏不仅免费,bug菌还郑重承诺,只要你学习此专栏,均能入门并理解Java SE,以全网最快速掌握Java语言,每章节源码均同步「Gitee」,你真值得拥有;学习就像滚雪球一样,越滚越大,带你指数级提升。

  码字不易,如果这篇文章对你有所帮助,帮忙给bugj菌来个一键三连(关注、点赞、收藏) ,您的支持就是我坚持写作分享知识点传播技术的最大动力。

  同时也推荐大家关注我的硬核公众号:「猿圈奇妙屋」 ;以第一手学习bug菌的首发干货,不仅能学习更多技术硬货,还可白嫖最新BAT大厂面试真题、4000G Pdf技术书籍、万份简历/PPT模板、技术文章Markdown文档等海量资料,你想要的我都有!

📣关于我

我是bug菌,CSDN | 掘金 | InfoQ | 51CTO | 华为云 | 阿里云 | 腾讯云 等社区博客专家,C站博客之星Top30,华为云2023年度十佳博主,掘金多年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者;全网粉丝合计 20w+;硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!免费白嫖最新BAT互联网公司面试真题、4000G PDF电子书籍、简历模板等海量资料,你想要的我都有,关键是你不来拿。


【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。