每日一道面试题:Java中序列化与反序列化

写在开头

哈喽大家好,在高铁上码字的感觉是真不爽啊,小桌板又拥挤,旁边的小朋友也比较的吵闹,影响思绪,但这丝毫不影响咱学习的劲头!哈哈哈,在这喧哗的车厢中,思考着这样的一个问题,Java中的对象是如何在各个方法,或者网络中流转的呢?
通过这个问题便引出了我们今天的主人公:序列化与反序列化

序列化:所谓的序列化就是将Java对象或数据结构转为字节序列的过程,以便于存储到数据库、内存、文件系统或者网络传输。
反序列化:而反序列化就是序列化的逆向操作将字节流转为Java对象的过程。

在这里插入图片描述

序列化的基本实现(JDK)

这样一看序列化是不是非常有用?毋容置疑,这是一个无形中都会用到的知识点!那么想要在Java中实现序列化该如何做呢?继续往下看。
其实只要做到2点,就可以实现基本的序列化功能:序列流(ObjectInputStream 和 ObjectOutputStream)、实现 Serializable 接口(一个标识型接口,没有具体的方法,仅是一种通知,告诉JVM这个对象需要序列化)
在这里插入图片描述

【示例代码】

/*** 测试序列化,反序列化* @author javabuild*/
public class TestSerializable implements Serializable {private static final long serialVersionUID = 5887391604554532906L;private int id;private String name;public TestSerializable(int id, String name) {this.id = id;this.name = name;}@Overridepublic String toString() {return "TestSerializable [id=" + id + ", name=" + name + "]";}@SuppressWarnings("resource")public static void main(String[] args) throws IOException, ClassNotFoundException {//序列化ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("TestSerializable.obj"));oos.writeObject("测试序列化");oos.writeObject(618);TestSerializable test = new TestSerializable(1, "JavaBuild");oos.writeObject(test);//反序列化ObjectInputStream ois = new ObjectInputStream(new FileInputStream("TestSerializable.obj"));System.out.println((String)ois.readObject());System.out.println((Integer)ois.readObject());System.out.println((TestSerializable)ois.readObject());}
}

输出:

测试序列化
618
TestSerializable [id=1, name=JavaBuild]

这种实现方式是JDK自带的,方便好用,易于实现,代码逻辑不复杂,但它有着诸多的致命缺陷,导致很多大厂不会使用这种方式。

1、不支持跨语言调用 : 如果调用的是其他语言开发的服务的时候就不支持了。
2、性能差:相比于其他序列化框架性能更低,主要原因是序列化之后的字节数组体积较大,导致传输成本加大。
3、存在安全问题:序列化和反序列化本身并不存在问题。但当输入的反序列化的数据可被用户控制,那么攻击者即可通过构造恶意输入,让反序列化产生非预期的对象,在此过程中执行构造的任意代码。

序列化的其他实现方式(Kryo)

除了JDK自带的实现方式,国内外的大厂们推出过不好的开源且好用的序列化协议,比如Hessian、Kryo、Protobuf、ProtoStuff。

Hessian
一个轻量级的,自定义描述的二进制 RPC 协议。Hessian 是一个比较老的序列化实现了,并且同样也是跨语言的。Dubbo2.x 默认启用的序列化方式是 Hessian2 ,但是,Dubbo 对 Hessian2 进行了修改,不过大体结构差别不大。

Protobuf
自于 Google,性能优秀,支持多种语言,同时还是跨平台的。就是在使用中过于繁琐,因为你需要自己定义 IDL 文件和生成对应的序列化代码。这样虽然不灵活,但是,另一方面导致 protobuf 没有序列化漏洞的风险。不过后续谷歌推出了升级版,进行了很多缺陷的优化,诞生了ProtoStuff。

Kryo

目前使用最广泛,好评诸多的就是具有高性能、高效率和易于使用和扩展等特点的Kryo, 目前像Twitter、Groupon、Yahoo 以及多个著名开源项目(如 Hive、Storm)中都在使用这款序列化工具。
【示例代码】
1、引入相应的pom依赖库

<!-- 引入 Kryo 序列化工具 -->
<dependency><groupId>com.esotericsoftware</groupId><artifactId>kryo</artifactId><version>5.4.0</version>
</dependency>

2、通过调用方法,通过二进制实现序列化与反序列化

public class KryoDemo {public static void main(String[] args) throws FileNotFoundException {Kryo kryo = new Kryo();kryo.register(KryoParam.class);KryoParam object = new KryoParam("JavaBuild", 123);Output output = new Output(new FileOutputStream("logs/kryo.bin"));kryo.writeObject(output, object);output.close();Input input = new Input(new FileInputStream("logs/kryo.bin"));KryoParam object2 = kryo.readObject(input, KryoParam.class);System.out.println(object2);input.close();}
}class KryoParam {private String name;private int age;public KryoParam() {}public KryoParam(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "KryoParam{" +"name='" + name + '\'' +", age=" + age +'}';}
}

序列化的细节知识点!

1、一般实现序列化接口后,还会有个serialVersionUID,它有什么作用?

答:SerialVersionUid 是为了序列化对象版本控制,告诉 JVM 各版本反序列化时是否兼容
如果在新版本中这个值修改了,新版本就不兼容旧版本,反序列化时会抛出InvalidClassException异常
仅增加了一个属性,希望向下兼容,老版本的数据都保留,就不用修改 删除了一个属性,或更改了类的继承关系,就不能不兼容旧数据,这时应该手动更新
SerialVersionUid

2、如果有些字段不想进行序列化怎么办?

答:对于不想进行序列化的变量,可以使用 transient 关键字修饰。transient
关键字的作用是:阻止实例中那些用此关键字修饰的的变量序列化;当对象被反序列化时,被 transient 修饰的变量值不会被持久化和恢复。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Ubuntu本地部署Nextcloud并结合内网穿透实现远程访问搭建个人云盘

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” 文章目录 摘要1. 环境搭建2. 测试局域网访问3. 内网穿透3.1 ubuntu本地安装cpolar3.2 创建隧道3.3 测试公网访…

百度云网盘下载速度如何提升到正常速度

引入问题 我们在下载代码学习资料的时候大多数都是百度云网盘&#xff0c;但是限速&#xff01;下载的十分的慢&#xff0c;有什么办法能让我们不开通会员就能享受正常速度呢&#xff1f; 当然有&#xff01; 解决百度云网盘下载速度过慢&#xff0c;提高到正常速度 点击右…

Python中如何将字符串变成数字?

字符串和数字是Python中常见的数据类型&#xff0c;而且在撰写Python程序的时候&#xff0c;也经常会遇到需要将字符串转换为数字的情况&#xff0c;那么Python中如何将字符串变成数字?有多种方法可以使用&#xff0c;接下来一起来看看具体内容介绍。 1、使用int()函数 int(…

数字图像处理(实践篇)二十七 Python-OpenCV 滑动条的使用

目录 1 涉及的函数 2 实践 1 涉及的函数 ⒈ setWindowProperty()用于设置GUI应用程序的属性 cv2.setWindowProperty(windowsName, prop_id, prop_value) 参数: ①

[机器学习]KNN——K邻近算法实现

一.K邻近算法概念 二.代码实现 # 0. 引入依赖 import numpy as np import pandas as pd# 这里直接引入sklearn里的数据集&#xff0c;iris鸢尾花 from sklearn.datasets import load_iris from sklearn.model_selection import train_test_split # 切分数据集为训练集和测试…

代码随想录算法训练营第四十六天|139.单词拆分、多重背包、背包问题总结

题目&#xff1a;139.单词拆分 文章链接&#xff1a;代码随想录 视频链接&#xff1a;LeetCode:139.单词拆分 题目链接&#xff1a;力扣题目链接 图释&#xff1a; class Solution { public:bool wordBreak(string s, vector<string>& wordDict) {// 将字符串的列…

C++之类继承隐式转换实例(二百五十七)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Hbase-2.4.11_hadoop-3.1.3集群_大数据集群_SSH修改默认端口22为其他端口---记录025_大数据工作笔记0185

其实修改起来非常简单,但是在大数据集群中,使用到了很多的脚步,也需要修改, 这里把,大数据集群,整体如何修改SSH端口,为22022,进行总结一下: 0.hbase-2.4.11的话,hbase集群修改默认SSH端口22,修改成22022,需要修改 需要修改/opt/module/hbase-2.4.11/conf/hbase-env.sh 这里…

解锁一些SQL注入的姿势

昨天课堂上布置了要去看一些sql注入的案例&#xff0c;以下是我的心得&#xff1a; ​​​​​​​ ​​​​​​​ ​​​​​​​ 1.新方法 打了sqli的前十关&#xff0c;我发现一般都是联合查询&#xff0c;但是有没有不是联合查询的方法呢&#xf…

如何搭建Nextcloud云存储网盘并实现无公网ip访问本地文件【内网穿透】

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【教学类-35-22】正式版 20240129名字字卡3.0(15CM正方形手工纸、先男后女,页眉是黑体包含全名,名字是红豆空心黑体)

作品展示 背景需求&#xff1a; 以下代码已经制作出页眉黑体、名字是空心黑体的样式&#xff1a; 【教学类-35-21】20240129名字字卡2.0&#xff08;15CM正方形手工纸、页眉是黑体&#xff0c;名字是红豆空心黑体&#xff09;-CSDN博客文章浏览阅读498次&#xff0c;点赞5次&…

Java多线程--同步机制解决线程安全问题方式一:同步代码块

文章目录 一、介绍二、原理三、同步锁机制&#xff08;1&#xff09;synchronized的锁是什么&#xff08;2&#xff09;同步操作的思考顺序&#xff08;3&#xff09;代码演示 四、同步代码块&#xff08;1&#xff09;同步代码块--案例11、案例12、分析同步原理3、案例1之this…

【Sql Server】新手一分钟看懂在已有表基础上增加字段和说明

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《Sql Server》系列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对…

单片机14-17

目录 LCD1602 LCD1602液晶显示屏 直流电机驱动&#xff08;PWM&#xff09; LED呼吸灯 直流电机调速 AD/DA&#xff08;SPI通信&#xff09; AD模数转换 DA数模转换 红外遥控&#xff08;外部中断&#xff09; 红外遥控 红外遥控电机调速 LCD1602 LCD1602液晶显示屏 …

使用dockers-compose搭建开源监控和可视化工具

简介 Prometheus 和 Grafana 是两个常用的开源监控和可视化工具。 Prometheus 是一个用于存储和查询时间序列数据的系统。它提供了用于监控和报警的数据收集、存储、查询和图形化展示能力。Prometheus 使用拉模型&#xff08;pull model&#xff09;&#xff0c;通过 HTTP 协议…

10s 内得到一个干净、开箱即用的 Linux 系统

安装 使用官方脚本安装我的服务器不行 官方脚本 mkdir instantbox && cd $_ bash <(curl -sSL https://raw.githubusercontent.com/instantbox/instantbox/master/init.sh) 下面是我的完整安装过程 mkdir /opt/instantbox cd /opt/instantbox 1.脚本文件 (这个没…

13.前端--CSS-盒子模型

1.盒子模型的组成 CSS 盒子模型本质上是一个盒子&#xff0c;封装周围的 HTML 元素&#xff0c;它包括&#xff1a;边框、外边距、内边距、和 实际内容 2.边框&#xff08;border&#xff09; 2.1 边框的使用 1、border设置元素的边框。边框有三部分组成:边框宽度(粗细) 边框…

【Git】项目管理笔记

文章目录 本地电脑初始化docker报错.gitignoregit loggit resetgit statusgit ls-filesgit rm -r -f --cached拉取仓库文件更新本地的项目报错处理! [rejected] master -> master (fetch first)gitgitee.com: Permission denied (publickey).error: remote origin already e…

在linux、window环境搭建kafka环境

一、搭建环境前置准备 下载kafka的官网 http://kafka.apache.org/downloads根据自己的需求选择版本,安装包不区分linux和windows环境,这一个安装包均可部署。 源代码包含kafka的代码文件,使用scala编写的。 二、linux环境 1. 上传安装包 我下载的版本是kafka_2.12-3.6.1…

盒子模型的内容总结

知识引入 1.认识盒子模型 在浏览网站时我们会发现内容都是按照区域划分的。这使得网页很工整、美观。在页面中&#xff0c;每一块区域分别承载不同的内容&#xff0c;使得网页的内容虽然零散&#xff0c;但是在版式排列上依然清晰有条理。如图1 图1 *承载内容的区域称为盒子…