【Java】Java序列化和反序列化

news2024/10/7 12:26:12

人不走空

                                                                      

      🌈个人主页:人不走空      

💖系列专栏:算法专题

⏰诗词歌赋:斯是陋室,惟吾德馨

# Java中的序列化和反序列化

在Java中,序列化是将对象的状态写入字节流的机制。它主要用于Hibernate、RMI、JPA、EJB和JMS技术中。

反序列化是序列化的逆操作,即将字节流转换为对象。序列化和反序列化过程是平台无关的,这意味着您可以在一个平台上对对象进行序列化,在另一个平台上进行反序列化。

为了序列化对象,我们调用ObjectOutputStream类的writeObject()方法,而为了反序列化,则调用ObjectInputStream类的readObject()方法。

我们必须实现Serializable接口才能序列化对象。

# Java序列化的优点

它主要用于在网络上传输对象的状态(即称为marshalling)。

图片

java.io.Serializable接口

Serializable是一个标记接口(没有数据成员和方法)。它用于“标记”Java类,以便这些类的对象可以获得某种能力。Cloneable和Remote也是标记接口。

Serializable接口必须由需要持久化其对象的类实现。

String类和所有包装类默认实现了java.io.Serializable接口。

让我们看下面给出的例子:

Student.java

import java.io.Serializable;  public class Student implements Serializable{   int id;   String name;   public Student(int id, String name) {    this.id = id;    this.name = name;   }  }  

在上面的示例中,Student类实现Serializable接口。现在它的对象可以转换为流。主类的实现显示在下一个代码中。

 

专属福利

👉点击领取:Java资料合集!650G!

ObjectOutputStream类

ObjectOutputStream类用于将基本数据类型和Java对象写入OutputStream。只有支持java.io.Serializable接口的对象才能写入流中。

构造函数

图片

重要方法

MethodDescription

1) public final void writeObject(Object obj) throws IOException {}

它将指定的对象写入 ObjectOutputStream。

2) public void flush() throws IOException {}

它刷新当前输出流。

3) public void close() throws IOException {}

它关闭当前输出流。

ObjectInputStream类

ObjectInputStream反序列化使用ObjectOutputStream编写的对象和基本数据。

构造函数

图片

重要方法

MethodDescription

1) public final Object readObject() throws IOException, ClassNotFoundException{}

它从输入流中读取一个对象。

2) public void close() throws IOException {}

它关闭 ObjectInputStream。.

# Java序列化的例子

在此示例中,我们将从上面代码的Student类序列化对象。 

ObjectOutputStream类的writeObject()方法提供了序列化对象的功能。我们正在将对象的状态保存在名为f.txt的文件中。

Persist.java

 
import java.io.*;    class Persist{     public static void main(String args[]){      try{      //Creating the object      Student s1 =new Student(211,"ravi");      //Creating stream and writing the object      FileOutputStream fout=new FileOutputStream("f.txt");      ObjectOutputStream out=new ObjectOutputStream(fout);      out.writeObject(s1);      out.flush();      //closing the stream      out.close();      System.out.println("success");      }catch(Exception e){System.out.println(e);}     }    }    

输出:

 
success

# Java反序列化的例子

反序列化是从序列化状态重构对象的过程。它是序列化的逆操作。让我们看一个示例,其中我们从反序列化对象中读取数据。

Deserialization是从序列化状态重构对象的过程。它是序列化的逆操作。让我们看一个示例,其中我们从反序列化对象中读取数据。

Depersist.java

 
import java.io.*;  class Depersist{   public static void main(String args[]){    try{    //Creating stream to read the object    ObjectInputStream in=new ObjectInputStream(new FileInputStream("f.txt"));    Student s=(Student)in.readObject();    //printing the data of the serialized object    System.out.println(s.id+" "+s.name);    //closing the stream    in.close();    }catch(Exception e){System.out.println(e);}   }  }  

输出:

 
211 ravi

# Java继承(IS-A关系)的序列化

如果一个类实现了Serializable接口,则所有它的子类也将可序列化。让我们看下面给出的例子:

SerializeISA.java

 
import java.io.Serializable;    class Person implements Serializable{     int id;     String name;     Person(int id, String name) {      this.id = id;      this.name = name;     }    }    class Student extends Person{     String course;     int fee;     public Student(int id, String name, String course, int fee) {      super(id,name);      this.course=course;      this.fee=fee;     }    }    public class SerializeISA  {     public static void main(String args[])   {        try{      //Creating the object      Student s1 =new Student(211,"ravi","Engineering",50000);      //Creating stream and writing the object      FileOutputStream fout=new FileOutputStream("f.txt");      ObjectOutputStream out=new ObjectOutputStream(fout);      out.writeObject(s1);      out.flush();      //closing the stream      out.close();      System.out.println("success");      }catch(Exception e){System.out.println(e);}      try{      //Creating stream to read the object      ObjectInputStream in=new ObjectInputStream(new FileInputStream("f.txt"));      Student s=(Student)in.readObject();      //printing the data of the serialized object      System.out.println(s.id+" "+s.name+" "+s.course+" "+s.fee);      //closing the stream      in.close();      }catch(Exception e){System.out.println(e);}     }    }  

输出:

 
success211 ravi Engineering 50000

SerializeISA类已序列化扩展了Person类的Student类对象,而Person类是可序列化的。父类属性继承到子类,因此如果父类是可序列化的,则子类也将是可序列化的。

# Java聚合(HAS-A关系)序列化

如果一个类引用另一个类,则所有引用必须是Serializable,否则将不执行序列化过程。在这种情况下,在运行时会抛出NotSerializableException。

Address.java

 
class Address{     String addressLine,city,state;     public Address(String addressLine, String city, String state) {      this.addressLine=addressLine;      this.city=city;      this.state=state;     }    }    

Student.java

 
import java.io.Serializable;  public class Student implements Serializable{   int id;   String name;   Address address;//HAS-A   public Student(int id, String name) {    this.id = id;    this.name = name;   }  }  

由于Address不可序列化,因此无法序列化Student类的实例。

注意:对象中的所有对象都必须是可序列化的。

# Java序列化中的静态数据成员

如果一个类中有任何静态数据成员,它将不被序列化,因为静态是类的一部分而不是对象。

Employee.java

 
class Employee implements Serializable{   int id;   String name;   static String company="SSS IT Pvt Ltd";//it won't be serialized   public Student(int id, String name) {    this.id = id;    this.name = name;   }  }  

# Java序列化数组或集合

规则:在数组或集合的情况下,数组或集合的所有对象必须是可序列化的。如果任何对象不可序列化,则序列化将失败。

Java中的Externalizable

Externalizable接口提供了以压缩格式将对象状态写入字节流的功能。它不是标记接口。

Externalizable接口提供两个方法:

  • public void writeExternal(ObjectOutput out) throws IOException

  • public void readExternal(ObjectInput in) throws IOException

Java暂时关键字

如果您不想序列化类的任何数据成员,可以将其标记为瞬态。

Employee.java

 
class Employee implements Serializable{   transient int id;   String name;   public Student(int id, String name) {    this.id = id;    this.name = name;   }  }  

现在,id将不会序列化,因此在序列化之后反序列化对象时,您将不会得到id的值。它始终返回默认值。在这种情况下,它将返回0,因为id的数据类型是整数。

访问下一页获取更多详细信息。

SerialVersionUID

运行时序列化过程将序列化类与每个可序列化类关联一个标识符,称为SerialVersionUID。它用于验证序列化对象的发送方和接收方。发送方和接收方必须相同。为验证它,使用SerialVersionUID。发送方和接收方必须具有相同的SerialVersionUID,否则在反序列化对象时将抛出InvalidClassException。我们还可以在Serializable类中声明自己的SerialVersionUID。

要这样做,您需要创建一个SerialVersionUID字段并为其分配一个值。它必须是长类型,并且带有静态和最终修饰符。建议在类中明确声明serialVersionUID字段,并将其私有化。例如:

 
private static final long serialVersionUID=1L;  

现在,可序列化类将如下所示:

Employee.java

 
import java.io.Serializable;    class Employee implements Serializable{     private static final long serialVersionUID=1L;     int id;     String name;     public Student(int id, String name) {      this.id = id;      this.name = name;     }    }    
 

图片


作者其他作品:

【Java】Spring循环依赖:原因与解决方法

OpenAI Sora来了,视频生成领域的GPT-4时代来了

[Java·算法·简单] LeetCode 14. 最长公共前缀 详细解读

【Java】深入理解Java中的static关键字

[Java·算法·简单] LeetCode 28. 找出字a符串中第一个匹配项的下标 详细解读

了解 Java 中的 AtomicInteger 类

算法题 — 整数转二进制,查找其中1的数量

深入理解MySQL事务特性:保证数据完整性与一致性

Java企业应用软件系统架构演变史

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1866137.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【教学类-64-05】20240625彩棒鱼骨图(二)AB排列 6.5*1CM 6选2根 30种

背景需求: 【教学类-64-04】20240619彩棒鱼骨图(一)6.5*1CM 6根棒子720种-CSDN博客文章浏览阅读897次,点赞23次,收藏13次。【教学类-64-04】20240619彩棒鱼骨图(一)6.5*1CM 6根棒子720种https:…

JAVA每日作业day6.26

ok了家人们,今天我们学习了面向对象-多态,话不多说我们一起来看看吧 一.多态概述 面向对象的第三大特性:封装、继承、多态 我们拿一个生活中的例子来看 生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一…

CAN总线学习之路

闻道有先后,术业有专攻。我们接触新的事物时总会有个学习过程,如今现场总线非常繁多,CAN总线就是其中不可忽视的一种,在此以个人的学习过程与大家共勉! 我大学时的专业是电子科学与技术,专业课程是数电、模…

从写下第1个脚本到年薪40W,我的测试开发心路历程!

对于任何职业来说,薪资始终都会是众多追求的重要部分。前几年测试行业还是风口,但是随着不断新鲜血液的加入,再加上就业大环境不好,企业也都在“降本增效”。目前内卷也是越来越激烈。不得不承认当下的现状,已经不仅仅…

视频分享的二维码怎么做?多种视频可用的二维码制作技巧

视频分享的快捷操作技巧可以在二维码生成器上来制作,与传统分享方式相比用二维码的方法能够更快捷,有利于用户能够在不下载视频占用空间的同时,就能够扫描二维码观看视频内容。视频二维码能够应用于很多的场景下,那么制作一个视频…

【Linux】使用ntpdate同步时间

ntpdate 是一个在 Linux 系统中用于同步系统时间的命令行工具,它通过与 NTP 服务器通信来调整本地系统时钟。然而,需要注意的是,ntpdate 已经被许多现代 Linux 发行版弃用。 安装 yum install -y ntpdate 查看时间 date同步时间 ntpdate ntp…

防火墙双机热备

防火墙双机热备 随着移动办公、网上购物、即时通讯、互联网金融、互联网教育等业务蓬勃发展,网络承载的业务越来越多,越来越重要。所以如何保证网络的不间断传输成为网络发展过程中急需解决的一个问题。 防火墙部署在企业网络出口处,内外网之…

想远程控制手机,用哪个软件好?

很多人都想知道安卓系统或iOS系统要如何实现手机远程控制手机、电脑远程控制手机,分别需要用到什么软件,这篇文章一次说清楚。 注意,安卓系统需要是7.0及以上版本,iOS系统需要是11及以上版本。具体使用步骤请点击关注,…

633. 平方数之和(中等)

633. 平方数之和 1. 题目描述2.详细题解3.代码实现3.1 Python3.2 Java内存溢出溢出代码正确代码与截图 1. 题目描述 题目中转:633. 平方数之和 2.详细题解 本题是167. 两数之和 II - 输入有序数组(中等)题目的变型,由两数之和变…

数字图像分析(第三部分)

文章目录 第11章 基于概率图模型的图像分析概率有向图模型因子分解生成式模型链式图条件独立性有向图模型的马尔科夫毯概率无向图模型模型定义概率无向图模型的因子分解条件随机场条件随机场的定义条件随机场的预测算法第12章 运动分析运动相机建模光流运动表达方法运动估计准则…

二维数组广度优先遍历-腐烂的苹果

一、问题描述 二、解题思路 此问题通过广度优先遍历来解决,模拟苹果发霉变坏的过程 1.初始时遍历网格,借助队列来储存所有发霉的苹果,统计好苹果个数 2.每一分钟队列内发霉苹果都会对周围的苹果起作用(向外部扩散)&am…

Python 高级编程:文件操作与错误处理

在前几篇文章中,我们介绍了Python的基本语法、函数和模块以及面向对象编程。这些知识对于大部分日常编程问题已经足够,但对于需要分析大数据的人来说,这些还不够。本章将介绍Python的文件操作以及错误处理与调试。 目录 文件操作读文件写文…

鸿蒙开发系统基础能力:【@ohos.systemTime (设置系统时间)】

设置系统时间 本模块用来设置、获取当前系统时间,设置、获取当前系统日期和设置、获取当前系统时区。 说明: 本模块首批接口从API version 7开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。 导入模块 import systemTime …

线性代数基础概念:行列式

目录 线性代数基础概念:行列式 1. 行列式的定义 1.1 递归定义 1.2 代数余子式定义 1.3 几何定义 2. 行列式的性质 2.1 行列式等于其转置的行列式 2.2 交换两行或两列,行列式变号 2.3 将一行或一列乘以一个数 k,行列式乘以 k 2.4 将…

初创企业合规管理中的企业合规义务边界问题

在初创企业的迅猛发展过程中,合规管理是确保公司可持续成长和避免潜在风险的关键因素。而在合规管理中,界定企业边界尤为重要,它关系到企业如何合理规划业务范围、管理内部外部关系以及维护企业形象和法律责任的清晰。 一、初创企业面临的合…

转让北京资产评估公司变更需要什么条件和要求

北京资产评估公司是有限责任公司。因为有限责任公司具有人合属性,股东的个人信用及相互关系直接影响到公司的风格甚至信誉,所以各国公司法对有限责任公司股东向公司外第三人的转让股权,多有限制性规定。大致可分为法定限制和约定限制两类。公…

没什么用的java技巧

1.将需要注入bean的方法,包装为静态方法,让其看起来不需要依赖注入等操作,但实际依然需要

关于mysq数据库备份的几个问题

1 mysql怎么双机热备? 或者怎么两个mysql服务器互相同步? MySQL的双机热备或两个MySQL服务器之间的互相同步,通常通过几种不同的同步机制来实现,这些机制确保了数据的实时更新和备份。以下是几种常见的同步方式及其实现步骤&…

程序员在企业中是如何做需求的

在企业中,一个需求从产生到完成生命周期是什么样的。 它可以分为这样的步骤: 需求分析 -> 设计(原型、功能、接口设计) -> 技术选型 -> 搭建项目框架 -> 编码(实现业务逻辑) -> 测试&#…

Python数据分析之-Oracle数据库连接

文章目录 cx_Oracle 介绍cx_Oracle运行原理cx_Oracle 安装linux环境安装windows环境安装 cx_Oracle 使用单独使用结合Pandas使用 参考资料 cx_Oracle 介绍 cx_Oracle 8是一个Python扩展模块,它提供了对Oracle数据库的访问能力。以下是cx_Oracle 8的一些关键特性和功…