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

fastjson-EnumDeserializer类及源码分析

本文以fastjson-1.2.83版本中EnumDeserializer类的源码来解释其工作原理和实现细节。 类结构概览EnumDeserializer是 FastJSON 用于将 JSON 反序列化为枚举类型的核心类。它支持通过枚举名称(Enum.name())反序列化通过枚举序号(Enum.ordinal())反序列化通过JSONField注解指定的别名反序列化大小写不敏感匹配高性能的哈希查找 核心成员变量protected final Class? enumClass; // 枚举类 protected final Enum[] enums; // 按哈希值排序的枚举数组 protected final Enum[] ordinalEnums; // 按序号排序的枚举数组 protected long[] enumNameHashCodes; // 枚举名称哈希值数组(已排序) 构造函数初始化流程构造函数是整个类的核心它预先计算了所有枚举常量的哈希值1. 获取所有枚举常量ordinalEnums (Enum[]) enumClass.getEnumConstants();2. 为每个枚举计算哈希值MapLong, Enum enumMap new HashMapLong, Enum(); for (int i 0; i ordinalEnums.length; i) { Enum e ordinalEnums[i]; String name e.name(); // 检查 JSONField 注解 JSONField jsonField null; try { Field field enumClass.getField(name); jsonField TypeUtils.getAnnotation(field, JSONField.class); if (jsonField ! null) { String jsonFieldName jsonField.name(); if (jsonFieldName ! null jsonFieldName.length() 0) { name jsonFieldName; // 使用注解指定的名称 } } } catch (Exception ex) { // skip } // 计算原始名称的哈希 long hash fnv1a_64_magic_hashcode; for (int j 0; j name.length(); j) { char ch name.charAt(j); hash ^ ch; hash * fnv1a_64_magic_prime; } enumMap.put(hash, e); // 计算小写名称的哈希(用于大小写不敏感匹配) long hash_lower fnv1a_64_magic_hashcode; for (int j 0; j name.length(); j) { char ch name.charAt(j); char lowerCh (ch A ch Z) ? (char)(ch 32) : ch; hash_lower ^ lowerCh; hash_lower * fnv1a_64_magic_prime; } if (hash ! hash_lower) { enumMap.put(hash_lower, e); } // 处理 JSONField.alternateNames() 备选名称 if (jsonField ! null) { for (String alterName : jsonField.alternateNames()) { long alterNameHash fnv1a_64_magic_hashcode; for (int j 0; j alterName.length(); j) { char ch alterName.charAt(j); alterNameHash ^ ch; alterNameHash * fnv1a_64_magic_prime; } if (alterNameHash ! hash alterNameHash ! hash_lower) { enumMap.put(alterNameHash, e); } } } }3. 存储和排序// 提取所有哈希值并排序 this.enumNameHashCodes new long[enumMap.size()]; int i 0; for (Long h : enumMap.keySet()) { enumNameHashCodes[i] h; } Arrays.sort(this.enumNameHashCodes); // 按排序后的哈希值顺序存储枚举 this.enums new Enum[enumNameHashCodes.length]; for (int j 0; j this.enumNameHashCodes.length; j) { long hash enumNameHashCodes[j]; Enum e enumMap.get(hash); this.enums[j] e; } 反序列化流程deserialze方法是实际执行反序列化的入口1. 处理整数类型(枚举序号)if (token JSONToken.LITERAL_INT) { int intValue lexer.intValue(); lexer.nextToken(JSONToken.COMMA); if (intValue 0 || intValue ordinalEnums.length) { throw new JSONException(parse enum enumClass.getName() error, value : intValue); } return (T) ordinalEnums[intValue]; }2. 处理字符串类型(主要场景)else if (token JSONToken.LITERAL_STRING) { String name lexer.stringVal(); lexer.nextToken(JSONToken.COMMA); if (name.length() 0) { return (T) null; // 空字符串返回 null } // 计算输入字符串的哈希 long hash fnv1a_64_magic_hashcode; long hash_lower fnv1a_64_magic_hashcode; for (int j 0; j name.length(); j) { char ch name.charAt(j); hash ^ ch; hash_lower ^ ((ch A ch Z) ? (ch 32) : ch); hash * fnv1a_64_magic_prime; hash_lower * fnv1a_64_magic_prime; } // 首先尝试原始哈希 Enum e getEnumByHashCode(hash); // 如果没找到尝试小写哈希 if (e null hash_lower ! hash) { e getEnumByHashCode(hash_lower); } if (e null lexer.isEnabled(Feature.ErrorOnEnumNotMatch)) { throw new JSONException(not match enum value, enumClass.getName() : name); } return (T) e; }3. 哈希查找方法public Enum getEnumByHashCode(long hashCode) { if (enums null) { return null; } // 二分查找已排序的哈希数组 int enumIndex Arrays.binarySearch(this.enumNameHashCodes, hashCode); if (enumIndex 0) { return null; // 没找到 } return enums[enumIndex]; } 关键设计决策1. 为什么使用 FNV-1a 哈希算法高性能FNV-1a 计算速度快适合频繁调用低碰撞在枚举名称这种短字符串上碰撞概率低确定性相同的输入总是产生相同的哈希值2. 为什么使用二分查找枚举常量数量通常很少(几十个)排序后的数组查找时间复杂度 O(log n)比 HashMap 有更好的局部性可能更快3. 为什么计算两种哈希(大小写敏感/不敏感)// 原始大小写 hash ^ ch; hash * fnv1a_64_magic_prime; // 转换为小写(如果是大写字母) hash_lower ^ ((ch A ch Z) ? (ch 32) : ch); hash_lower * fnv1a_64_magic_prime;这样实现了大小写不敏感的枚举匹配用户输入 YCX 或 ycx 都能匹配到YCX枚举。 性能优化策略1. 预先计算在构造函数中计算所有可能的哈希值避免了每次反序列化时的重复计算2. 内存布局优化使用两个并行数组enumNameHashCodes[]和enums[]保持相同索引便于二分查找后快速获取枚举3. 哈希复用// 初始化哈希值 long hash fnv1a_64_magic_hashcode; // 迭代计算 for (int j 0; j name.length(); j) { char ch name.charAt(j); hash ^ ch; // XOR hash * fnv1a_64_magic_prime; // 乘以质数 } 使用示例枚举定义public enum Status { JSONField(name success, alternateNames {ok, good}) SUCCESS, JSONField(name failed, alternateNames {error, bad}) FAILED, PENDING }可匹配的输入通过序号0→SUCCESS通过名称SUCCESS→SUCCESS通过注解名称success→SUCCESS通过备选名称ok或good→SUCCESS大小写不敏感Success或success→SUCCESS⚠️ 异常处理无效序号intValue 0 || intValue ordinalEnums.length→ 抛出异常无效字符串哈希查找返回 null → 可能返回 null 或抛出异常(取决于Feature.ErrorOnEnumNotMatch)空字符串返回 nullnull 值返回 null 设计模式应用策略模式根据输入类型(整数/字符串)选择不同的反序列化策略字符串又分为大小写敏感/不敏感两种策略缓存模式预计算并缓存所有枚举的哈希值避免运行时重复计算工厂模式通过getEnumByHashCode方法生产枚举实例 与其他反序列化器的对比特性FastJSON EnumDeserializerJacksonGson哈希算法FNV-1a 64位无无查找方式二分查找线性查找/HashMap线性查找大小写不敏感支持配置支持配置支持注解支持JSONFieldJsonCreatorSerializedName性能高中中 性能分析时间复杂度构造函数O(n * m)其中 n 是枚举数量m 是名称平均长度哈希计算O(m)每次反序列化哈希查找O(log k)其中 k 是哈希值数量(包括备选名称)空间复杂度存储所有哈希值和枚举引用O(k)通常 k 接近 n(枚举数量) 总结EnumDeserializer的设计体现了 FastJSON 在性能优化上的追求预计算策略在初始化时计算所有可能的哈希值高效的哈希算法FNV-1a 适合短字符串计算快速优化查找排序数组 二分查找比 HashMap 更快灵活匹配支持大小写不敏感、注解别名、备选名称健壮性完善的异常处理和边界条件检查这个实现平衡了性能、功能和内存使用是 FastJSON 高效反序列化的一个典型代表。

相关文章:

fastjson-EnumDeserializer类及源码分析

本文以fastjson-1.2.83版本中 EnumDeserializer 类的源码,来解释其工作原理和实现细节。 🎯 类结构概览 EnumDeserializer 是 FastJSON 用于将 JSON 反序列化为枚举类型的核心类。它支持: 通过枚举名称(Enum.name())反序列化通过枚举序号(Enu…...

sse哈工大C语言编程练习45

2026 年 3 月 17 日 收获: 判断直角三角形时,两边的平方和减第三边的平方和小于 0.1 即可认为是直角三角形,主要看题目给的测试用例,确定精度。取余和除法第二个数都不能为 0,若遇到则输出错误提示信息,直接…...

Java面试题1000+附答案大全(合适各级Java开发人员)

作为一名优秀的程序员,技术面试都是不可避免的一个环节,一般技术面试官都会通过自己的方式去考察程序员的技术功底与基础理论知识。 2026 年的互联网行业竞争越来越严峻,面试也是越来越难,很多粉丝朋友私信希望我出一篇面试专题或…...

迷你世界UGC3.0脚本Wiki数组变量数据管理接口 Array

迷你世界UGC3.0脚本WikiMenuOn this pageSidebar Navigation快速入门欢迎MOD、组件介绍什么是Lua编程组件介绍组件说明组件互相操作组件函数组件属性事件触发器事件管理组件事件管理函数库服务模块世界模块管理接口 World对象模块管理接口 GameObject角色模块管理接口 Actor玩家…...

Python 生成 PowerPoint 演示文件图表教程

免费编程软件「pythonpycharm」 链接:https://pan.quark.cn/s/48a86be2fdc0周五下午三点,部门群里弹出一条消息:"各位,下周一汇报的各季度运营数据PPT,今晚12点前发我合并。"小王盯着屏幕愣了五秒&#xff0…...

env SHARP_IGNORE_GLOBAL_LIBVIPS=1 npm --loglevel error --silent --no-fund --no-audit install -g open

根据你提供的错误信息,npm install 在安装 OpenClaw 时失败,可能涉及多个层面的原因。以下是系统化的排查与解决方案:一、核心问题定位 从错误日志 npm install failed for openclawlatest 和命令参数 SHARP_IGNORE_GLOBAL_LIBVIPS1 推测&…...

GESP2026年3月认证C++一级( 第三部分编程题(2)数字替换)

一、🌟故事:Alice讨厌数字41、Alice 是一个很可爱的同学,不过她有一个小小的习惯:她 不喜欢数字 4。(1)因为在很多地方:4 的谐音像 “死”(2)但她特别喜欢:8因…...

OpenClaw 引爆 AI Agent 革命,边缘计算才是真正的“决战场“

一个奥地利程序员,60天改写了开源历史2025 年底,奥地利开发者 Peter Steinberger 发布了一个小型开源项目——Clawdbot。Steinberger 并不是一个普通程序员。他是 PDF 软件公司 PSPDFKit 的创始人,这家公司曾被以约 1 亿欧元估值出售。在离开…...

前字节员工自曝:北京买房年薪百万,却不如在成都月薪3万活得明白

来自:推荐一个程序员编程资料站:http://cxyroad.com副业赚钱专栏:https://xbt100.top2024年IDEA最新激活方法后台回复:激活码CSDN免登录复制代码插件下载:CSDN复制插件以下是正文。一位前字节跳动员工在社交媒体的帖子…...

2026必备!10个降AI率软件降AIGC网站评测:开源免费必看,学术降重全维度推荐

在人工智能技术日益渗透学术领域的今天,论文写作中AI痕迹的识别和处理已成为学者们不得不面对的重要课题。随着AIGC率检测技术的不断升级,传统的AI生成内容更容易被系统识别并标记,这给论文的原创性和通过率带来了巨大挑战。而AI降重工具的出…...

拖延症福音!全行业通用降AIGC工具 千笔·降AIGC助手 VS 灵感风暴AI

在AI技术迅速发展的今天,越来越多的学生、研究人员和职场人士开始借助AI工具辅助论文写作,提升效率与质量。然而,随着学术审查标准的不断提高,AI生成内容的痕迹越来越容易被识别,导致论文面临“AI率超标”的风险。许多…...

三极管工作原理解析

三极管知识全面解析 1. 三极管基础概念与结构 1.1 基本定义 三极管(Transistor)是一种半导体器件,具有电流放大和开关作用,是现代电子技术的核心元件。三极管由三个掺杂不同的半导体区域构成,分别是发射区、基区和集电区。 1.2 类型分类 类型 结构特点 符号表示 主要特…...

从 O(n²) 暴力到 O(n·log n) 蝶形运算——OpenCV dft() 源码全链路拆解,附频域去条纹噪声实战

一、你的图像处理为什么需要频域? 做图像处理的程序员,十个里面有九个是从空间域起步的。模糊用 GaussianBlur(),锐化用拉普拉斯算子,去噪用中值滤波——这些操作直觉上很好理解,每个像素和它的邻居做一轮加权平均就完事了。 但总有一天你会碰到这样的场景:一张图片上出…...

2026鸿蒙开发认证全攻略:从零基础到持证通关,抢占生态红利

在万物互联时代,鸿蒙系统作为华为自主研发的分布式操作系统,正加速渗透智能终端、物联网、工业互联网等多个领域,成为国内科技产业自主可控的核心支撑。鸿蒙开发认证作为华为官方唯一权威的技能认证体系,不仅是检验开发者鸿蒙技术…...

2026红帽认证(RHCSA/RHCE/RHCA)全攻略:从零基础到架构师,解锁Linux运维高薪密码

在Linux运维、DevOps、云原生赛道竞争日趋激烈的今天,红帽认证(RHCSA/RHCE/RHCA)早已超越“技能证书”的范畴,成为企业筛选核心技术人才的“硬通货”、从业者突破职业瓶颈的“金钥匙”。不同于市面上侧重理论的认证,红…...

C++ 隐式类型转换全解析

C 隐式类型转换全解析(核心规则场景风险)参考回答: 首先,对于内置类型,低精度的变量给高精度变量赋值会发生隐式类型转换,其次,对于只存在 单个参数的构造函数的对象构造来说,函数调…...

SECURITY ISSUES [radio wave]

SECURITY ISSUES [radio wave] 无限设备的安全问题一直使用有线的我,其实有线比无线传输更加快,信号更加稳定,信号辐射也小,我能想到唯一的缺点就是费线和到处都是线!!!!...

Java入门第162课——HTML 基础语法与文档结构

1.1 Web 核心基础认知 1.1.1 Web 工作原理 Web 采用客户端 - 服务器(C/S) 架构,核心流程: 客户端(浏览器)通过 URL 向服务器发送请求; 服务器接收请求后处理,返回 HTML/CSS/JS 等资源; 浏览器解析资源,以图形化方式展示页面。 1.1.2 Web 相关技术分类 服务器端技术…...

智捷云软网关:数据采集的智能桥梁

前言 在物联网应用中,设备数据采集是核心环节之一。传统的硬件网关虽然稳定,但成本高、部署复杂、扩展性差。软网关作为一种新兴的解决方案,以其灵活、经济、易部署的特点,正在成为物联网数据采集的新选择。今天要为大家介绍的是…...

迷你世界UGC3.0脚本Wiki道具实例介绍

迷你世界UGC3.0脚本WikiMenuOn this pageSidebar Navigation快速入门欢迎MOD、组件介绍什么是Lua编程组件介绍组件说明组件互相操作组件函数组件属性事件触发器事件管理组件事件管理函数库服务模块世界模块管理接口 World对象…...

一文搞懂信息安全核心技术:加密、认证与数字证书——软件设计师备考指南

目录 一、对称加密 vs 非对称加密:两种核心加密范式 二、数字签名与信息摘要:保障完整性与不可否认性 三、数字证书:解决公钥信任问题 四、技术对比总结 五、常见误区纠正 非 VIP 用户可前往公众号“前端基地”进行免费阅读,文章链接如下…...

微软澄清:5年后不会用AI重写Win11,C语言也不会被淘汰

5年后将淘汰C语言 微软澄清:不会用AI重写Win11系统快科技官方原创作者2025.12.2421:28在快科技于12月24日所发布的消息当中,在这之前,有一位工程师,其在个人页面宣告,有相关情况表明微软会在2030年的时候删去全部用C以…...

工程人必备!批量CAD版本转换,效率提升 10 倍!

如果你负责一整套项目图纸,几十张甚至上百张 DWG 文件, 需要统一转换成低版本归档或发给施工方, 一张一张手动转换,不仅枯燥,还极其浪费时间。 浩辰 CAD 看图王的批量版本转换功能,就是为解决这类痛点而…...

MySQL--》快速提高查询效率:SQL语句优化技巧与实践

目录 插入数据 order by与group by优化 limit、count、update优化 插入数据 在对数据库当中进行插入数据操作,通常我们都会使用insert进行插入数据,可由于每次insert都会和数据库建立连接,频繁的插入数据就会导致效率上的降低&#xff0c…...

隧道环境有毒有害气体在线监测系统方案

利用物联网、数据采集、大数据分析等技术,通过构建稳定、可靠的工业物联网络,工业智能网关能够将实时数据准确、快速地传输至监控管理中心,实现数据可视化,助力管理员全面了解隧道运行期间的有毒气体浓度实时状况,并为…...

2026 本科毕业论文 AI 工具全景指南:从 Paperzz 到高效写作矩阵,一键解锁毕业季从容节奏

Paperzz-AI官网免费论文查重复率AIGC检测/开题报告/文献综述/论文初稿paperzz - 毕业论文-AIGC论文检测-AI智能降重-ai智能写作https://www.paperzz.cc/dissertation 又到本科毕业季,毕业论文成了无数学生的 “心头大山”:选题卡壳、文献难寻、图表公式无…...

华硕电脑键盘全部失灵

华硕电脑键盘全部失灵前言一、故障排查二、发现问题三、使用方法总结前言 故障情况描述: 键盘无法使用,键盘除开机键外全部失灵,关机后,如果没断电,键盘常亮 打开机器,故障复现,果然是完全失效…...

作为一个普通的程序员,到底应不应该转型AI大模型?

在程序员圈子中,技术转型近年来一直是热门话题。随着AI技术的迅猛发展,优秀人才短缺,程序员向AI大模型转型似乎成为了一条通往职场先机的路径。但是,这条转型之路是否容易走,成功率又如何呢?作为一个普通的…...

Java开发者AI转型大模型全攻略:4大方向+学习路径+避坑指南

本文探讨Java开发者如何在AI时代实现职业转型,提出四个方向:AI增强型工程师、AI工程化、垂直领域AI解决方案、AI产品化。详细阐述各方向目标、实践建议及优势,提供系统学习路径和资源推荐,并给出避免"调参侠"陷阱等实用…...

国内软件工程相关核心期刊汇总与投稿指南

中文核心期刊要目总览收录 1. 软件学报 (顶级期刊) 主办单位:中国科学院软件研究所收录情况:EI、CSCD核心、中文核心影响因子:较高,软件工程领域权威研究方向:软件理论、方法、技术、工具等 2. 计算机研究与发展 主办单…...