当前位置: 首页 > news >正文

Gson 自动生成适配器插件

在json解析方面 我们常见有下面几方面困扰

1. moshi code-gen能自动生成适配器,序列化效率比gson快,但是自定义程度不如gson,能java kotlin共存 且解决了默认值的问题
2.gson api 强大自由,但是 第一次gson的反射缓存比较慢,而且生成对象都是反射,除非主动注册com.google.gson.InstanceCreator 这个人工机械
3.kotlin ks 效率还行,但是不支持java  api自由性没有gson强
目前可能更偏向gson 同时也要解决默认值的问题

最大的一处难点是在jvm 获取申明的枚举,先看一下gson是怎么解决的
 

  private static final class EnumTypeAdapter<T extends Enum<T>> extends TypeAdapter<T> {private final Map<String, T> nameToConstant = new HashMap<String, T>();private final Map<T, String> constantToName = new HashMap<T, String>();public EnumTypeAdapter(final Class<T> classOfT) {try {// Uses reflection to find enum constants to work around name mismatches for obfuscated classes// Reflection access might throw SecurityException, therefore run this in privileged context;// should be acceptable because this only retrieves enum constants, but does not expose anything elseField[] constantFields = AccessController.doPrivileged(new PrivilegedAction<Field[]>() {@Override public Field[] run() {Field[] fields = classOfT.getDeclaredFields();ArrayList<Field> constantFieldsList = new ArrayList<Field>(fields.length);for (Field f : fields) {if (f.isEnumConstant()) {constantFieldsList.add(f);}}Field[] constantFields = constantFieldsList.toArray(new Field[0]);AccessibleObject.setAccessible(constantFields, true);return constantFields;}});for (Field constantField : constantFields) {@SuppressWarnings("unchecked")T constant = (T)(constantField.get(null));String name = constant.name();SerializedName annotation = constantField.getAnnotation(SerializedName.class);if (annotation != null) {name = annotation.value();for (String alternate : annotation.alternate()) {nameToConstant.put(alternate, constant);}}nameToConstant.put(name, constant);constantToName.put(constant, name);}} catch (IllegalAccessException e) {throw new AssertionError(e);}}@Override public T read(JsonReader in) throws IOException {if (in.peek() == JsonToken.NULL) {in.nextNull();return null;}return nameToConstant.get(in.nextString());}@Override public void write(JsonWriter out, T value) throws IOException {out.value(value == null ? null : constantToName.get(value));}}

gson的实现 是第一次反射(TypeAdapter 对于rawType gson本身会缓存)
他这个时候能读取到class,但是编译注解这个时候并不能得到class,
那么又查询了官方文档,官方的解释不在是class 而是Element和TypeName的类

翻译如下:
宽松地说,返回直接被该元素包围的元素。 类或接口被认为包含它直接声明的字段、方法、构造函数和成员类型。 包包含其中的顶级类和接口,但不被视为包含子包。 模块将包包含在其中。 封闭的元素可以包括隐式声明的强制元素。 其他种类的元素目前不被认为包含任何元素; 但是,随着 API 或编程语言的发展,这种情况可能会发生变化。
返回:
包含的元素,如果没有则为空列表
API注意事项:
可以使用 ElementFilter 中的方法来隔离某些类型的元素。
也可以看看:
TypeElement.getEnclosureElements、PackageElement.getEnheldElements、ModuleElement.getEnheldElements、Elements.getAllMembers
吉林斯
8.8.9 默认构造函数
吉林斯
8.9 枚举
修改
9
规格
联合项目管理系统

那么我理解jvm 元数据matadata存储在这个数组里面

我打印了一下 得到枚举的全部申明 包括enum_entry(不是enum class)还有valueOf等方法

枚举数据在元数据里面 values(),valueOf(java.lang.String),HELLO,HI,FINE,THANKS,intValue,TestEnum(int),getIntValue()

得按类型过滤出 申明的enum_constant

        val enumConstants = enumElement?.enclosedElements?.filter {it.kind == ElementKind.ENUM_CONSTANT} ?: listOf()

最终折腾了半天 终于出来了


import com.google.gson.annotations.SerializedName
import javax.lang.model.element.ElementKind/*** xxf:生成编译时枚举常量池生成hashmap*/
internal class EnumTypeParser {internal val nameToConstant: MutableMap<String, Any> = mutableMapOf()internal val constantToName: MutableMap<Any, String> = mutableMapOf()/*** 枚举数据在元数据里面 values(),valueOf(java.lang.String),HELLO,HI,FINE,THANKS,intValue,TestEnum(int),getIntValue()* @param enumElement*/constructor(enumElement: javax.lang.model.element.Element?) {val enumConstants = enumElement?.enclosedElements?.filter {it.kind == ElementKind.ENUM_CONSTANT} ?: listOf()enumConstants.forEach { constant ->val annotation: SerializedName? = constant.getAnnotation(SerializedName::class.java)var name = constant.simpleName.toString()//本身名字nameToConstant[name] = constant//注解名字 和别名名字if (annotation != null) {name = annotation.valuefor (alternate in annotation.alternate) {nameToConstant[alternate] = constant}}nameToConstant[name] = constantconstantToName[constant] = name}//排序一下 代码好看一点nameToConstant.toSortedMap().run {nameToConstant.clear()nameToConstant.putAll(this)}//排序一下 代码好看一点constantToName.toSortedMap(Comparator { o1, o2 ->constantToName[o1]!!.compareTo(constantToName[o2]!!)}).run {constantToName.clear()constantToName.putAll(this)}}}

运行效果:

这样就替代了gson 枚举0反射,同样的读写都是o(1)

更多类型的实现 请参考我的开源项目 gson_plugin
这个可能是业界最快的json解析方式 最快的json解析框架

相关文章:

Gson 自动生成适配器插件

在json解析方面 我们常见有下面几方面困扰 1. moshi code-gen能自动生成适配器,序列化效率比gson快,但是自定义程度不如gson,能java kotlin共存 且解决了默认值的问题 2.gson api 强大自由,但是 第一次gson的反射缓存比较慢,而且生成对象都是反射,除非主动注册com.google.gson…...

React创建项目

React创建项目 提前安装好nodejs再进行下面的操作&#xff0c;通过node -v验证是否安装 1.设置源地址 npm config set registry https://registry.npmmirror.com/2.确认源地址 npm config get registry返回如下 https://registry.npmmirror.com/3.输入命令 npx create-re…...

Redis5新特性-stream

Stream队列 Redis5.0 最大的新特性就是多出了一个数据结构 Stream&#xff0c;它是一个新的强大的 支持多播的可持久化的消息队列&#xff0c;作者声明 Redis Stream 地借鉴了 Kafka 的设计。 生产者 xadd 追加消息 xdel 删除消息&#xff0c;这里的删除仅仅是设置了标志位&am…...

删除PPT文件的备注内容

解决方案的工作经常汇报以及经常做ppt的回报工作&#xff0c;但是删除备注很痛苦。 在网上或者拿历史的ppt文件修改后&#xff0c;需要删除ppt备注内容以及删除ppt个人文件信息的办法&#xff1a; 现象&#xff1a;很多备注信息&#xff0c;需要删除 解决办法一、 文件--信息-…...

2023年亚太杯APMCM数学建模大赛B题玻璃温室小气候调控

2023年亚太杯APMCM数学建模大赛 B题 玻璃温室小气候调控 原题再现 温室作物的产量受各种气候因素的影响&#xff0c;包括温度、湿度和风速[1]。其中&#xff0c;适宜的温度和风速对植物生长至关重要[2]。为了调节玻璃温室内的温度、风速等气候因素&#xff0c;在温室设计中常…...

Oracle 查询语句限制只选择最前面几行,和最后面几行的实现方式。

查询最前面几行 在Oracle中&#xff0c;可以使用 ROWNUM 关键字来限制查询结果的行数。要选择前10条记录&#xff0c;可以使用以下查询语句&#xff1a; SELECT * FROM your_table WHERE ROWNUM < 10;实际查询时将your_table替换为要查询的表名。以上查询将返回表中的前10…...

.NET Core6.0 MVC+layui+SqlSugar 简单增删改查

HTML部分: {ViewData["Title"] "用户列表"; } <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>用户列表</title><meta name"renderer" content"webkit"><meta …...

在 Mac 上使用浅色或深色外观

在 Mac 上&#xff0c;选取苹果菜单 >“系统设置”&#xff0c;然后点按边栏中的“外观” 。&#xff08;你可能需要向下滚动。&#xff09;选择右侧的“浅色”、“深色”或“自动”。 “浅色”表示不会发生变化的浅色外观。 “深色”表示不会发生变化的深色外观。“深色模式…...

华为手环关闭智能适时测量

问题 使用华为手环并使用华为创新研究APP后&#xff0c;会自动打开智能适时测量开关&#xff0c;此开关开启后&#xff0c;手环会在睡眠时间自动测量血氧&#xff0c;增加手环功耗从而影响续航&#xff0c;用户可根据自身需求决定是否开启&#xff0c;下文介绍如何找到此开关。…...

1-Hadoop原理与技术

单选题 题目1&#xff1a;安装Hadoop集群时&#xff0c;是在哪个文件指定哪些机器作为集群的从机&#xff1f; 选项: A datanode B slaves C yarn-site.xml D core-site.xml 答案&#xff1a;B ------------------------------ 题目2&#xff1a;Hadoop配置文件所在目录是哪…...

YoloV5改进策略:Swift Parameter-free Attention,无参注意力机制,超分模型的完美迁移

摘要 https://arxiv.org/pdf/2311.12770.pdf https://github.com/hongyuanyu/SPAN SPAN是一种超分网络模型。SPAN模型通过使用参数自由的注意力机制来提高SISR的性能。这种注意力机制能够增强重要信息并减少冗余,从而在图像超分辨率过程中提高图像质量。 具体来说,SPAN模…...

DAPP开发【04】测试驱动开发

测试驱动开发(Test Driven Development)&#xff0c;是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码&#xff0c;然后只编写使测试通过的功能代码通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码&#xff0c…...

Raspberry Pi 2, 2 of n - Pi 作为 IoT 消息代理

目录 介绍 环境 先决条件 - 设置静态 IP 地址 安装 Mosquitto 启动/停止 Mosquitto 配置先决条件 - 安装 mqtt_spy 配置 Mosquitto 配置 Mosquitto - 无安全性 测试 Mosquitto 配置 - 无安全性 配置 Mosquitto - 使用密码身份验证 Mosquitto 测试 - 带密码验证 概括 介绍 在本文…...

linux服务器环境搭建(使用yum 安装mysql、jdk、redis)

一:yum的安装 1:下载yum安装包并解压 wget http://yum.baseurl.org/download/3.2/yum-3.2.28.tar.gz tar xvf yum-3.2.28.tar.gz 2.进入yum-3.2.28文件夹中进行安装,执行安装指令 cd yum-3.2.28 sudo apt install yum 3.更新版本 yum check-update yum update yum cle…...

互联网Java工程师面试题·Spring Boot篇·第二弹

目录 8、什么是 YAML&#xff1f; 9、如何实现 Spring Boot 应用程序的安全性&#xff1f; 10、如何集成 Spring Boot 和 ActiveMQ&#xff1f; 11、如何使用 Spring Boot 实现分页和排序&#xff1f; 12、什么是 Swagger&#xff1f;你用 Spring Boot 实现了它吗&#xff1f; …...

【西南交大swjtu微机与接口技术实验】D/A变换实验实验三:波形发生器

做一个存档。实验要求与电路连接见参考指导书。 1、主程序产生锯齿波 2、按下KK1输出五个周期的三角波&#xff0c;继续输出被中断的锯齿波 3、按下KK2输出五个周期的方波&#xff0c;继续输出被中断的锯齿波 程序代码 IOY0 EQU 0600H DA EQU IOT000H*2SSTACK SEGMENT STA…...

【每日一题】从二叉搜索树到更大和树

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;中序遍历的反序方法二&#xff1a;后缀数组 写在最后 Tag 【中序遍历】【二叉树】【2023-12-04】 题目来源 1038. 从二叉搜索树到更大和树 题目解读 在二叉搜索树中&#xff0c;将每一个节点的值替换成树中大于等于该…...

@Scheduled,Quartz,XXL-JOB三种定时任务总结

Scheduled&#xff0c;Quartz&#xff0c;XXL-JOB三种定时任务总结 一、Scheduled 简介 Scheduled 是 Spring 框架中用于声明定时任务的注解。通过使用 Scheduled 注解&#xff0c;你可以指定一个方法应该在何时执行&#xff0c;无需依赖外部的调度器。 这个注解通常与Enab…...

开会做笔记的时候用什么软件比较好?

在工作生涯中&#xff0c;会经历很多大大小小的会议&#xff0c;而如何快速准确记录下会议上重要的内容&#xff0c;成了很多上班族的必修课。在会上做笔记&#xff0c;选择什么样的工具才能事半功倍&#xff0c;成了一个值得深思的问题。而经过一段时间的测评后&#xff0c;我…...

HTML CSS JavaScript的网页设计

一、网页界面效果&#xff1a; 二、HTML代码&#xff1a; <!DOCTYPE html> <!-- 声明文档类型--> <html lang"en"> …...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

【网络安全】开源系统getshell漏洞挖掘

审计过程&#xff1a; 在入口文件admin/index.php中&#xff1a; 用户可以通过m,c,a等参数控制加载的文件和方法&#xff0c;在app/system/entrance.php中存在重点代码&#xff1a; 当M_TYPE system并且M_MODULE include时&#xff0c;会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

day36-多路IO复用

一、基本概念 &#xff08;服务器多客户端模型&#xff09; 定义&#xff1a;单线程或单进程同时监测若干个文件描述符是否可以执行IO操作的能力 作用&#xff1a;应用程序通常需要处理来自多条事件流中的事件&#xff0c;比如我现在用的电脑&#xff0c;需要同时处理键盘鼠标…...

PH热榜 | 2025-06-08

1. Thiings 标语&#xff1a;一套超过1900个免费AI生成的3D图标集合 介绍&#xff1a;Thiings是一个不断扩展的免费AI生成3D图标库&#xff0c;目前已有超过1900个图标。你可以按照主题浏览&#xff0c;生成自己的图标&#xff0c;或者下载整个图标集。所有图标都可以在个人或…...

Java多线程实现之Runnable接口深度解析

Java多线程实现之Runnable接口深度解析 一、Runnable接口概述1.1 接口定义1.2 与Thread类的关系1.3 使用Runnable接口的优势 二、Runnable接口的基本实现方式2.1 传统方式实现Runnable接口2.2 使用匿名内部类实现Runnable接口2.3 使用Lambda表达式实现Runnable接口 三、Runnabl…...

HTML中各种标签的作用

一、HTML文件主要标签结构及说明 1. <&#xff01;DOCTYPE html> 作用&#xff1a;声明文档类型&#xff0c;告知浏览器这是 HTML5 文档。 必须&#xff1a;是。 2. <html lang“zh”>. </html> 作用&#xff1a;包裹整个网页内容&#xff0c;lang"z…...

Ray框架:分布式AI训练与调参实践

Ray框架&#xff1a;分布式AI训练与调参实践 系统化学习人工智能网站&#xff08;收藏&#xff09;&#xff1a;https://www.captainbed.cn/flu 文章目录 Ray框架&#xff1a;分布式AI训练与调参实践摘要引言框架架构解析1. 核心组件设计2. 关键技术实现2.1 动态资源调度2.2 …...

LeetCode - 148. 排序链表

目录 题目 思路 基本情况检查 复杂度分析 执行示例 读者可能出的错误 正确的写法 题目 148. 排序链表 - 力扣&#xff08;LeetCode&#xff09; 思路 链表归并排序采用"分治"的策略&#xff0c;主要分为三个步骤&#xff1a; 分割&#xff1a;将链表从中间…...