返回顶部
首页 > 资讯 > 后端开发 > Python >Java中序列化和反序列化的完整讲解
  • 339
分享到

Java中序列化和反序列化的完整讲解

Java序列化反序列化Java序列化Java反序列化 2022-11-16 00:11:06 339人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录一、序列化二、序列化和反序列化的应用三、序列化和反序列化地实现3.1.jdk类库提供的序列化api3.2.序列化要求3.3.实现java序列化和反序列化的三种方法四、Custom

一、序列化

1.1.Serialization(序列化):

将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)

1.2.deserialization(反序列化)

将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化

二、序列化和反序列化的应用

两个进程在远程通信时,可以发送多种数据,包括文本、图片、音频、视频等,这些数据都是以二进制序列的形式在网络上传输。

java是面向对象开发方式,一切都是java对象,想要在网络中传输java对象,可以使用序列化和反序列化去实现,发送发需要将java对象转换为字节序列,然后在网络上传送,接收方收到字符序列后,会通过反序列化将字节序列恢复成java对象。

java序列化的优点:

  • 实现了数据的持久化,通过序列化可以把数据持久地保存在硬盘上(磁盘文件)。
  • 利用序列化实现远程通信,在网络上传输字节序列

三、序列化和反序列化地实现

3.1.JDK类库提供的序列化API

java.io.ObjectOutputStream    

表示对象输出流,其中writeObject(Object obj)方法可以将给定参数的obj对象进行序列化,将转换的一连串的字节序列写到指定的目标输出流中。

java.io.ObjectInputStream

该类表示对象输入流,该类下的readObject(Object obj)方法会从源输入流中读取字节序列,并将它反序列化为一个java对象并返回

3.2.序列化要求

实现序列化的类对象必须实现了Serializable类或Externalizable类才能被序列化,否则会抛出异常

3.3.实现java序列化和反序列化的三种方法

现在要对student类进行序列化和反序列化,遵循以下方法:

3.3.1.方法一

若student类实现了serializable接口,则可以通过objectOutputstream和objectinputstream默认的序列化和反序列化方式,对非transient的实例变量进行序列化和反序列化

3.3.2. 方法二

若student类实现了serializable接口,并且定义了writeObject(objectOutputStream out)和

readObject(objectinputStream in)方法,则可以直接调用student类的两种方法进行序列化和反序列化

3.3.3.方法三

若student类实现了Externalizable接口,则必须实现readExternal(Objectinput in)和writeExternal(Objectoutput out)方法进行序列化和反序列化 

3.4.序列化步骤 

public static void main(String[] args) {
    File filename = new File("E:/Student1.txt");
    try {
            // 第一步,创建一个输出流对象,它可以包装一个输出流对象,如:文件输出流
            FileOutputStream fileOutputStream = new FileOutputStream(filename);
            ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);
            // 第二步,通过输出流对象的 writeObject()方法写对象,从 java 输出到本地文件 out
            out.writeObject("第一次输出:第一次打卡哦");
            out.writeObject("第二次输出:第二次打卡");
    } catch (IOException e) {
            e.printStackTrace();
    }
}

3.5.反序列化操作

public static void main(String[] args) {
    File filename = new File("E:/Student1.txt");
    try {
            // 第一步:创建文件输入流对象
            FileInputStream fileInputStream = new FileInputStream(filename);
            ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);
            // 调用readObject()方法,本地文件读取数据,输入到程序当中
            System.out.println(inputStream.readObject());
            System.out.println(inputStream.readObject());
    } catch (IOException e) {
            e.printStackTrace();
    } catch (ClassNotFoundException e) {
            e.printStackTrace();
    }
}

为了保证正确读取数据,对象输出流写入对象的顺序与对象输入流读取对象的顺序一致

四、CustomerForm 类序列化和反序列化演示

4.1.先创建一个实现了serializable接口的CustomerForm 类

Serializable (/ˈsɪˌriəˌlaɪzəbl/) 序列化

import lombok.Data;
import java.io.Serializable;
import java.util.List;
 

@Data
public class CustomerForm implements Serializable {
    protected String requestCode;
    protected List<Customer> reqData;
    
    private transient String msg;
    private static String name = "被static修饰的name";
}

把CustomerForm类的对象序列化到CustomerForm.txt 文件(E:/CustomerForm.txt)中,并对文件进行反序列化获取数据:

public static void main(String[] args) {
    FileOutputStream fileOutputStream = null;
    ObjectOutputStream out = null;
    FileInputStream fileInputStream = null;
    ObjectInputStream inputStream = null;       
    try {            
        File file = new File("E:/CustomerForm.txt");            
        if (file.exists()){                
            System.out.println("文件已存在");            
        } else {          
            file.createNewFile();            
        }            
        CustomerForm customerForm = new CustomerForm();           
        customerForm.setRequestCode("1-2-3-4-5-6-7-8-9");            
        // 序列化 第一步,创建一个输出流对象,它可以包装一个输出流对象,如:文件输出流            
        fileOutputStream = new FileOutputStream(file);            
        out = new ObjectOutputStream(fileOutputStream);            
        // 序列化 第二步,通过输出流对象的 writeObject()方法写对象,从 java 输出到本地文件 out            
        out.writeObject(customerForm);            
        // 反序列化 第一步:创建文件输入流对象            
        fileInputStream = new FileInputStream(file);            
        inputStream = new ObjectInputStream(fileInputStream);           
        // 反序列化 第二步:调用readObject()方法,本地文件读取数据,输入到程序当中            
        System.out.println(inputStream.readObject());        
    } catch (IOException e) {            
        e.printStackTrace();       
    } catch (ClassNotFoundException e) {            
        e.printStackTrace();       
    } finally {
        out.close();
        fileOutputStream.close();
        fileInputStream.close();
        inputStream.close();
    }
}

序列化之后本地文件访问结果:

反序列化结果:

4.2.transient 关键字

transient ( /ˈtrænʃ(ə)nt/)瞬变的

transient 修饰的属性不能参加序列化

以上程序重新执行:

public static void main(String[] args) {       
    try {            
        File file = new File("E:/CustomerForm.txt");            
        if (file.exists()){                
            System.out.println("文件已存在");            
        } else {          
            file.createNewFile();            
        }            
        CustomerForm customerForm = new CustomerForm();           
        customerForm.setRequestCode("1-2-3-4-5-6-7-8-9");   
        
        customerForm.setMsg("此属性不能参加序列化");         
        // 序列化 第一步,创建一个输出流对象,它可以包装一个输出流对象,如:文件输出流            
        FileOutputStream fileOutputStream = new FileOutputStream(file);            
        ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);            
        // 序列化 第二步,通过输出流对象的 writeObject()方法写对象,从 java 输出到本地文件 out            
        out.writeObject(customerForm);            
        // 反序列化 第一步:创建文件输入流对象            
        FileInputStream fileInputStream = new FileInputStream(file);            
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);           
        // 反序列化 第二步:调用readObject()方法,本地文件读取数据,输入到程序当中            
        System.out.println(inputStream.readObject());        
    } catch (IOException e) {            
        e.printStackTrace();       
    } catch (ClassNotFoundException e) {            
        e.printStackTrace();       
    }
}

执行结果:

从结果看出 被transient关键字修饰的变量 msg 赋值内容没有被序列化,被修改为null,被static修饰的属性不能被实例化

五、Externalizable接口实现序列化与反序列化

Externalizable 可外部化的

Externalizable接口继承Serializable接口,实现Externalizable接口需要实现readExternal()方法和writeExternal()方法,这两个方法是抽象方法,对应的是serializable接口的readObject()方法和writeObject()方法,可以理解为把serializable的两个方法抽象出来。Externalizable没有serializable的限制,static和transient关键字修饰的属性也能进行序列化。

5.1.Externalizable 的不同点

Externalizable没有serializable的限制,transient关键字修饰的属性也能进行序列化

5.2.CustomerForm 实现类 Externalizable

import lombok.Data;
import java.io.Serializable;
import java.util.List;
 

@Data
public class CustomerForm implements Externalizable{
    protected String requestCode;
    protected List<Customer> reqData;
    private transient String msg;
    private static String name = "被static修饰的name";
 
    @Override
    public void writeExternal(ObjectOutput out) throws IOException {
        out.writeObject(requestCode);
        out.writeObject(msg);
        out.writeObject(reqData);
    }
 
    @Override
    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
        requestCode = (String) in.readObject();
        msg = (String) in.readObject();
        reqData = (List<Customer>) in.readObject();
    }
}

实现 Externalizable 类 后需要重写 writeExternal()、readExternal() 方法

5.3.Externalizable 实现序列化和反序列化

public static void main(String[] args) {       
    try {            
        File file = new File("E:/CustomerForm.txt");            
        if (file.exists()){                
            System.out.println("文件已存在");            
        } else {          
            file.createNewFile();            
        }            
        CustomerForm customerForm = new CustomerForm();           
        customerForm.setRequestCode("1-2-3-4-5-6-7-8-9");   
        customerForm.setMsg("该属性被transient修饰");         
        // 序列化 第一步,创建一个输出流对象,它可以包装一个输出流对象,如:文件输出流            
        FileOutputStream fileOutputStream = new FileOutputStream(file);            
        ObjectOutputStream out = new ObjectOutputStream(fileOutputStream);            
        // 序列化 第二步,通过输出流对象的 writeObject()方法写对象,从 java 输出到本地文件 out            
        out.writeObject(customerForm);            
        // 反序列化 第一步:创建文件输入流对象            
        FileInputStream fileInputStream = new FileInputStream(file);            
        ObjectInputStream inputStream = new ObjectInputStream(fileInputStream);           
        // 反序列化 第二步:调用readObject()方法,本地文件读取数据,输入到程序当中            
        System.out.println(inputStream.readObject());        
    } catch (IOException e) {            
        e.printStackTrace();       
    } catch (ClassNotFoundException e) {            
        e.printStackTrace();       
    }
}

执行结果:

可以看到被transient关键字修饰的变量msg已经参与了实例化,被static修饰的变量不能被实例化

总结

序列化和反序列化可以过这两种方式来实现:

1、Bean对象可以通过Serializable接口实现序列化与反序列化

2、Bean对象可以通过Externalizable接口实现序列化与反序列化

不同点

1、Externalizable接口实现实例化,需要重写 writeExternal()、readExternal() 方法

2、Externalizable接口实现实例化,不受 transient关键字限制

3、Serializable接口实现,transient关键字修饰后,不能参与实例化

4、被static修饰的变量(都)不能被实例化

原因:被static修饰的属性是所有类共享的,如果可以序列化,就会出现下面的情况,当我们序列化某个类的一个对象到某个文件后,这个文件中的对象的那个被static修饰的属性值会固定下来,当另外一个普通的的对象修改了该static属性后,我们再去反序列化那个文件中的对象,就会得到和后面的对象不同的static属性值,这显然违背了static关键字诞生的初衷

到此这篇关于Java中序列化和反序列化的完整讲解的文章就介绍到这了,更多相关Java序列化内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Java中序列化和反序列化的完整讲解

本文链接: https://lsjlt.com/news/173009.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Java中序列化和反序列化的完整讲解
    目录一、序列化二、序列化和反序列化的应用三、序列化和反序列化地实现3.1.JDK类库提供的序列化API3.2.序列化要求3.3.实现java序列化和反序列化的三种方法四、Custom...
    99+
    2022-11-16
    Java序列化 反序列化 Java序列化 Java 反序列化
  • Java序列化和反序列化(详解)
    一、理解Java序列化和反序列化 Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。 deserializa...
    99+
    2023-09-11
    java 开发语言
  • Java序列化与反序列化
    目录Java 序列化与反序列化序列化APIObjectOutputStreamObjectInputStreamserialVersionUIDTransient (瞬态变量)实例理...
    99+
    2023-05-14
    Java序列化 Java反序列化
  • [Java反序列化]—Shiro反序列化(一)
    环境配置:  IDEA搭建shiro550复现环境_普通网友的博客-CSDN博客 漏洞原理: Apache Shiro框架提供了记住密码的功能(RememberMe),用户登录成功后会生成经过加密并编码的cookie。在服务端对remem...
    99+
    2023-09-03
    java 开发语言
  • PHP序列化和反序列化
    一.什么是序列化和反序列化 php类与对象 类是定义一系列属性和操作的模板,而对象,就是把属性进行实例化,完事交给类里面的方法,进行处理。 `。尝试构造payload: ...
    99+
    2023-08-31
    php 开发语言
  • Java之对象的序列化和反序列化
    对象的序列化和反序列化1)对象序列化,就是将Object对象转换成byte序列,反之叫对象的反序列化。2)序列化流(ObjectOutputStream),是字节的过滤流—— writeObject()方法 反序列化流(Object...
    99+
    2019-09-29
    Java IO流 对象 序列化 反序列化
  • Java序列化和反序列化_动力节点Java学院整理
    一、序列化和反序列化的概念  把对象转换为字节序列的过程称为对象的序列化。  把字节序列恢复为对象的过程称为对象的反序列化。  对象的序列化主要有两种用途:  1) 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中;  2) 在网络...
    99+
    2023-05-31
    java 序列化 反序列化
  • Java中如何实现序列化和反序列化
    本篇文章给大家分享的是有关Java中如何实现序列化和反序列化,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。序列化序列化:将对象转换为二进制序列在网络中传输或保存到磁盘反序列化:...
    99+
    2023-06-15
  • 一文详解Java对象的序列化和反序列化
    目录一、什么是 Java 序列化和反序列化?二、序列化和反序列化的实现方式三、序列化和反序列化的注意事项四、序列化和反序列化的优点和缺点五、总结Java 对象的序列化和反序列化是一种...
    99+
    2023-05-16
    Java对象序列化 Java对象反序列化 Java对象序列化和反序列化
  • 图文浅析Java序列化和反序列化
    序列化 序列化:将对象转换为二进制序列在网络中传输或保存到磁盘 反序列化:从网络或磁盘中将二进制序列转换为对象 注意: 对象必须实现Serializable接口 对象的所有属性都要...
    99+
    2024-04-02
  • Java序列化和反序列化示例分析
    这期内容当中小编将会给大家带来有关Java序列化和反序列化示例分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。序列化是为了把Java对象转化为字节序列(字节流)的过程。然后深拷贝是通过对流的操作来实现的...
    99+
    2023-06-26
  • Java序列化和反序列化示例介绍
    以前用序列化都是一些方法需要才实现的,后来业务需求要深拷贝才去研究。参阅了别人博客得出一些总结。 序列化是为了把Java对象转化为字节序列(字节流)的过程。然后深拷贝是通过对流的操作...
    99+
    2024-04-02
  • Java对象的序列化与反序列化详解
    一、序列化和反序列化的概念把对象转换为字节序列的过程称为对象的序列化,把字节序列恢复为对象的过程称为对象的反序列化。对象的序列化主要有两种途径:Ⅰ . 把对象的字节序列永久地保存到硬盘上,通常存放在一个文件中Ⅱ.  在网络上传送对...
    99+
    2023-05-31
    java 序列化 反序列化
  • 深入理解Java序列化与反序列化
    目录一、前言1.1 String1.2 Integer二、案例2.1 编写大象类2.2 大象测试类三、运行结果一、前言 序列化:将对象转换为二进制序列在网络中传输或保存到磁盘 反序列...
    99+
    2024-04-02
  • 序列化与反序列化
    序列化(pickling)   把变量从内存中变成可存储或传输的过程 反序列化(unpickling)   把变量内容从序列化的对象重新读到内存里的过程 序列化&反序列化的意义  在程序运行过程中,对象可在内存中被自由的修改  一...
    99+
    2023-01-31
    序列 化与 序列化
  • PHP的序列化和反序列化详情
    目录一、PHP 为什么要反序列化?二、PHP如何反序列化?三、PHP反序列化漏洞1、常用 的魔术方法2、漏洞产生条件3、题目一、PHP 为什么要反序列化? PHP程序执行结束以后会将...
    99+
    2024-04-02
  • PHP的序列化和反序列化入门
    什么是PHP序列化 serialize() //将一个对象转换成一个字符串unserialize() //将字符串还原成一个对象 通过序列化与反序列化我们可以很方便的在PHP中进行对象的传递。本质上反序列化是没有危害的。但是如果...
    99+
    2023-10-27
    android
  • Java对象的序列化和反序列化是什么
    这篇文章主要介绍了Java对象的序列化和反序列化是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java对象的序列化和反序列化是什么文章都会有所收获,下面我们一起来看看吧。Java 对象的序列化和反序列化是...
    99+
    2023-07-06
  • java序列化和反序列化有什么作用
    Java的序列化和反序列化主要用于以下几个方面:1. 数据持久化:可以将Java对象转化为字节序列,并将其写入文件或者数据库,从而实...
    99+
    2023-09-25
    java
  • PHP中的序列化和反序列化是什么
    这篇“PHP中的序列化和反序列化是什么”文章,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要参考一下,对于“PHP中的序列化和反序列化是什么”,小编整理了以下知识点,请大家跟着小编的步伐一步一步的慢慢理解,接下来就让...
    99+
    2023-06-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作