Gson源码解读

news2024/9/23 15:23:55

一,概述

gson作为流行的json工具,笔者使用较多。本文主要目的是解读下Gson的源码实现,就没有然后了。

二,实例

实例如下图所示,笔者简单调用gson的toJson方法获得json字符串,fromJson则从json字符串解析成对应类型实例。

三,源码解读

1,构造方法

在创建gson时,虽说笔者只是简单new了一个Gson,但其内部初始化过程还是很多的,笔者看下。

可以看到,Gson构造方法默认了许多参数,我们看下真正的构造方法参数,

笔者简单介绍下各个参数的意思,

(1)excluder:此类选择要省略的字段和类型,如根据修饰符等。

(2)fieldNamingStrategy:将Gson配置为在序列化和反序列化期间将特定的命名策略应用于对象的字段。

(3)instanceCreators:自定义Type类型的实例生成器的Map。

(4)serializeNulls:是否支持序列化null字段。

(5)generateNonExecutableJson:通过在生成的JSON前面加一些特殊文本,使输出的JSON在Javascript中不可执行

(6)complexMapKeySerialization:如果映射键是序列化JSON形式的复杂类型(即非基元),则启用此功能只会更改序列化形式。

(7)longSerializationPolicy:将Gson配置为对长对象和长对象应用特定的序列化策略。

(8)objectToNumberStrategy:将Gson配置为在对象的反序列化过程中应用特定的数字策略。

(9)numberToNumberStrategy:将Gson配置为在number的反序列化过程中应用特定的数字策略。

(10)prettyPrinting:将Gson配置为输出适合页面进行漂亮打印的Json。此选项仅影响Json序列化。

(11)lenient:将Gson配置为允许不严格遵守JSON规范的JSON数据。

(12)escapeHtmlChars:默认情况下,Gson转义HTML字符,如<>等。使用此选项可将Gson配置为按原样传递HTML字符。

(13)datePattern:将Gson配置为根据提供的模式序列化Date对象。可以多次调用此方法或setDateFormat(int),但只有最后一次调用才会用于决定序列化格式。

(14)builderFactories:配置Gson以进行自定义序列化或反序列化。

(15)serializeSpecialFloatingPointValues:特殊浮点数处理策略,(NaN,Infinity,-Infinity)。

(16)useJdkUnsafe:禁止使用JDK的sun.msc.Unsafe。

(17)reflectionFilters:添加反射访问筛选器。反射访问筛选器阻止Gson使用反射对某些类进行序列化和反序列化。筛选器中的逻辑指定这些是哪些类。

读者可自行了解默认参数。

笔者通过对Gson构造方法参数解读,发现Gson采用了适配器设计模式和策略设计模式,便于后续扩展,记录一下。

接下来,笔者看下一些核心接口的定义。

2,InstanceCreator

根据type创建实例。

3,TypeAdapterFactory

根据type返回对应TypeAdapter,

4,TypeAdapter

TypeAdapter是一个抽象类,抽象方法有两个,如下,

这提供了对应TypeAdapter的序列化和反序列化操作。众所周知,Gson内置了许多TypeAdapter类,笔者简单看下,

在Gson构造方法中,factories内置了一些TypeAdapterFactory,看下,

有byte、short、char、int、long、double、float、uri、uuid、url、原子类等。笔者重点介绍下最后添加的ReflectiveTypeAdapterFactory,即所有object序列化/反序列化策略默认反射方式。我们看下ReflectiveTypeAdapterFactory的create方法,

如果是record类,则返回record适配器。否则,返回FieldReflectionAdapter。FieldReflectionAdapter继承ReflectiveTypeAdapterFactory$Adapter,跟进看下read方法,

核心是通过BoundField去遍历对象所有field,读取值或者写入值。

read中提供了三个抽象方法,如下

createAccmulator,笔者理解这是创建对象接口。

readField在反序列化时将值反射进对象中。

笔者跟进write中

核心仍是遍历Field,通过BoundField写入值到json中。

这里笔者了解到BoundField,跟进看下。

其唯一实现在ReflectiveTypeAdapterFactory#createBoundField方法中,

不多跟了,笔者下文看toJson实现。

5,toJson

创建了一个StringWriter,跟进toJson,

这里创建了一个JsonWriter,跟进toJson。

这里根据type类型获取一个Adapter,如果是java基本类型,这里就是基本类型的适配器。如果不是,且没有添加对应的适配器,那么就使用反射Adapter,即ReflectiveTypeAdapterFactory$FieldReflectionAdapter。

最重要的是获取到FieldReflectionAdapter中BoundFields,笔者跟进getBoundFields看下,

通过getDeclaredFields方法获取所有fields,遍历,

(1)对每个field,通过getFieldName获得序列化名,

如果没有@SerializedName注解,通过fieldNamingPolicy策略去获取名字,否则通过注解内容获取。注意返回的是个list,意思是一个field可以有多个别名,然后分别创建BoundField对象。

回到正轨,跟进createBoundField,但在跟进之前,注意到fieldType,这个是什么呢?笔者提醒读者,Gson支持解析简单泛型,而java是泛型擦除的,怎么拿到的呢?

笔者为了搞明白这个问题,准备通过调试看看,

如笔者所见,返回了一个ParameterizedTypeImpl,其存在一个方法,可以返回实际泛型对象,但注意这是参数化Type才拥有。而Field#getGenericType,如果是泛型Field,就能返回一个ParameterizedTypeImpl,感兴趣的读者可自行了解。

笔者继续跟进$Gson$Types.resolve方法,

因此,泛型信息看来不是完全擦除了。

回到正轨,跟进createBoundField。简单将fieldType(ParameterizedTypeImpl),field,name,以及一些策略保存到BoundField中,随后就能完成一个Bean的序列化了。

6,fromJson

笔者从toJson知道,参数化的Type可以保存一些泛型信息,如笔者验证

ok,这不是重点,我们跟进,fromJson。

创建一个StringReader,传入json,跟进fromJson,

拿到adapter,解析,直接看反射适配器,

通过creatAccumulator创建对象,通过JsonReader#nextName方法读取。默认创建对象工厂是Gson构造方法中构建的,笔者看下,

先从instanceCreators或获取构造器,如果没有则通过反射创建一个默认对象,笔者不细跟踪了。最后将field设置进这个对象中。

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

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

相关文章

基于单片机的造纸纸浆液位控制系统结构设计

摘要:为适应无人化与高效化制浆造纸生产体系,造纸企业趋于以嵌入式技术优化造纸过 程中的纸浆液位控制系统,以单片机与传感器相互耦合实现纸浆液位控制。本文基于单片机 设计了造纸纸浆液位控制系统,其结构由控制模块、信息采集模块、物联网模…

ASP.NET Core 自定义解压缩提供程序

写在前面 在了解ASP.NET Core 自定义请求解压缩中间件的应用时,依据官方文档操作下来碰到了几个问题,这边做个记录。 关键点就是配置 Content-Encoding,参数需要和代码中添加的提供程序的Key保持一致; builder.Services.AddRequ…

(bean配置类的注解开发)学习Spring的第十三天

bean配置类的注解开发 问题提出 用类充当配置文件 applicationcontext.xml : Configuration注解标识此类为配置类,替代原有xml文件 看原配置文件applicationcontext.xml代码 <?xml version"1.0" encoding"UTF-8"?> <beans xmlns"http:/…

ctfshow——文件包含

文章目录 web 78——php伪协议第一种方法——php://input第二种方法——data://text/plain第三种方法——远程包含&#xff08;http://协议&#xff09; web 78——str_replace过滤字符php第一种方法——远程包含&#xff08;http://协议&#xff09;第二种方法——data://&…

FPGA项目(16)——基于FPGA的音乐演奏电路

1.设计要求 能在实验箱上&#xff0c;循环播放一段音乐。&#xff08;需要源码的直接看最后一节&#xff09; 2.设计原理 组成乐曲的每个音符的发音频率值及其持续的时间是乐曲能连续演奏所需要的两个基本要素&#xff0c;问题是如何来获取这两个要素所对应的数值以及通过纯硬件…

2024.2.3

单向循环链表的头插 头删 尾插和尾删 //头结点插入 Linklist insere_element(Linklist head,datatype element) {Linklist screat();s->dataelement;if(NULLhead){heads;}else{Linklist phead;while(p->next!head){pp->next;}s->nexthead;heads;p->nexthead;}r…

探索前端开发框架:React、Angular 和 Vue 的对决(一)

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

Linux下vim命令详解

vim #创建或编辑新的文件 #这将在当前目录下创建一个名为fi.txt的新文本文件。如果文件已经存在&#xff0c;将会编辑现有文件。 [rootsever ~]#vim fi.txt #对于普通的文本编辑操作&#xff0c;可以使用以下键盘命令&#xff1a; - i&#xff1a;进入插入模式&#xff…

[职场] 英语面试自我介绍 #微信#笔记#媒体

英语面试自我介绍 英语面试自我介绍1 I am very happy to introduce myself here.I was born in Liaoning Province.I graduated from Nankai University and majored in International Trade.I like music and reaing books,especially economical books.It is my honor to ap…

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测

回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测 目录 回归预测 | Matlab基于OOA-LSSVM鱼鹰算法优化最小二乘支持向量机的数据多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于OOA-LSSVM鱼鹰算法…

Java数组声明、创建、赋值和使用

目录 数组的定义数组的创建访问数组元素遍历数组数组实例分析 数组的定义 数组是相同类型数据的有序集合。数组描述的是相同类型的若干个数据&#xff0c;按照一定的先后次序排列组合而成。其中&#xff0c;每一个数据称作一个元素&#xff0c;每个元素可以通过一个索引&#…

[word] word表格两列互换 #学习方法#其他

word表格两列互换 Word表格也常用的数据表&#xff0c;在使用表格时&#xff0c;不管是编辑数据&#xff0c;调整数据&#xff0c;还是删除数据&#xff0c;都是有小技巧的&#xff0c;今天给大家分享word表格两列互换的小技巧&#xff0c;简单又实用。 1、两列互换 那么两列…

太强了,AI数字人从制作到变现一次搞定

AI数字人从制作到变现 如果说GPT类大模型是我们人类的第二大脑&#xff0c;数字人就是我们人类在互联网上的第二个身体。随着 AI 的迅速发展&#xff0c;2024 年 AI 模型开始从大型语言模型向大型视觉模型转变。数字人技术作为其分支之一&#xff0c;正日益成为科技、娱乐、教…

算法42:天际线问题(力扣218题)---线段树

218. 天际线问题 城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度&#xff0c;请返回 由这些建筑物形成的 天际线 。 每个建筑物的几何信息由数组 buildings 表示&#xff0c;其中三元组 buildings[i] [lefti, righti, heig…

中国大学生计算机设计大赛与大数据应用主题赛

中国大学生计算机设计大赛 与大数据应用主题赛 中国大学生计算机设计大赛&#xff08;简称“大赛”或4C&#xff09;始筹于2007年&#xff0c;首届于2008年&#xff0c;已经举办了16届80场赛事。是我国高校面向本科生最早的赛事之一&#xff0c;由教育部计算机类教指委发起举…

Android Button background 失效

问题 Android Button background 失效 详细问题 笔者开发Android项目&#xff0c;期望按照 android:background中所要求的颜色展示。 实际显示按照Android 默认颜色展示 解决方案 将xml的Button 组件修改为<android.widget.Button> 即将代码 <Buttonandroid:l…

有趣的CSS - css loading动画

Loading动画 整体效果核心代码html 代码&#xff1a;css 部分代码&#xff1a; 完整代码如下html 页面&#xff1a;css 样式&#xff1a;页面渲染效果&#xff1a; 整体效果 这个 Loading 效果主要用 css3 的 animation 属性配合 border 属性来实现的。 可以用作在下拉列表 Loa…

如何写好论文——(14)写作时如何定义和描述研究目标

当我们有了一个具体的细化的研究目标之后&#xff0c;我们需要把它清晰准备描述给我们的读者&#xff0c;并用它来指导我们的研究活动。 一、有方向 我们所选择的具体的研究目标一定要有明确的目标指向&#xff0c;那就是我们的长远目标。 二、有边界 我们要明确自己的研究…

在WORD中设置公式居中编号右对齐设置方式

1 软件环境 Office Microsoft Office LTSC 专业增强版2021 2 最终效果 3 操作步骤 编辑公式&#xff1b;光标定位到公式的最后&#xff08;不是行的最后&#xff09;&#xff1b;输入#编号光标定位在公式最后&#xff08;不是行的最后&#xff09;&#xff0c;按Enter键回车…

【计算机视觉】目标检测 |滑动窗口算法、YOLO、RCNN系列算法

一、概述 首先通过前面对计算机视觉领域中的卷积神经网络进行了解和学习&#xff0c;我们知道&#xff0c;可以通过卷积神经网络对图像进行分类。 如果还想继续深入&#xff0c;会涉及到目标定位(object location)的问题。在图像分类的基础上(Image classification)的基础上…