获取泛型,泛型擦除,TypeReference 原理分析
说明
- @author blog.jellyfishmix.com / JellyfishMIX - github
- LICENSE GPL-2.0
获取泛型,泛型擦除
- 下图中示例代码是一个工具类用于生成 csv 文件,需要拿到数据的类型,使用反射感知数据类型的字段,来填充表字段名。
- 可以看到泛型 T 没有类似 getClass() 的方法,因为编译后泛型 T 会被擦除,在字节码中不存在 T 这个类型,所以没办法通过 T 来获取某些信息。方法签名中的
java.util.List<T>
编译后会变成java.util.List
。 - 解决方式是显式传入
Class<?> clazz
来指定数据类型。
泛型嵌套
Class<?> clazz
只能传递一层数据类型,无法解决泛型嵌套时的数据类型传递问题。- 对于泛型嵌套,例如
List<List<Map<String, Person>>>
,这样的类型。如果使用Class<?> clazz
来传递,只能感知到最外层的List.class
,内层泛型还是会出现泛型擦除的情况。 - 完整地传递泛型嵌套,还是需要感知到具体的泛型。
TypeReference 原理分析–感知具体泛型
- 出现泛型嵌套情况时,获取完整的泛型,也是序列化组件需要面对的问题。解决方法例如 jackson 提供的 TypeReference。
泛型没有完全擦除
- javac 编译后没有把所有持有泛型的位置都做擦除。
- 编译后的字节码中,子类的类签名显式指定了传递给父类的泛型。
根据子类获取向父类传递的泛型理论基础
作为 TypeReference 的替代品,定义一个 CustomTypeHandler,通过演义来展示 TypeReference 的原理,
public abstract class CustomTypeHandler<T extends Object> {
}
再定义一个 ChildCustomTypeHandler 子类,继承父类时声明泛型。
public class ChildCustomTypeHandler extends CustomTypeHandler<List<List<Map<String, Person>>>> {private String tag;
}
编译项目后,使用 jclasslib(一个 IDEA 查看字节码的插件) 查看 ChildCustomTypeHandler.class 字节码,发现 Attributes -> Signature 属性中,记录了类签名,类签名显式指定了传递给父类的泛型。
class 文件结构
jvm 定义了 u1, u2, u4 三种数据结构来表示 1, 2, 4 字节无符号整数。class 文件采用类似 C 语言的结构体来存储数据,如下所示:
ClassFile {u4 magic;u2 minor_version;u2 major_version;u2 constant_pool_count;cp_info constant_pool[constant_pool_count-1];u2 access_flags;u2 this_class;u2 super_class;u2 interfaces_count;u2 interfaces[interfaces_count];u2 fields_count;field_info fields[fields_count];u2 methods_count;method_info methods[methods_count];u2 attributes_count;attribute_info attributes[attributes_count];
}
中文说明:
魔数(Magic Number)
版本号(Minor&Major Version)
常量池(Constant Pool)
类访问标记(Access Flags)
类索引(This Class)
超类索引(Super Class)
接口表索引(Interfaces)
字段表(Fields)
方法表(Methods)
属性表(Attributes)
类的字节码 Attributes -> Signature 属性中,记录了类签名,类签名会显式指定传递给父类的泛型。这是根据子类获取向父类传递的泛型的理论基础,及 TypeReference 的理论基础。
根据子类获取向父类传递的泛型 demo
- getActualTypeArguments 可能会存在多个泛型,例如 Map<K,V> 所以会返回 Type[] 数组。
- 根据 CustomTypeHandler 的约定,只能向 CustomTypeHandler 传递一个最外层 T,因此这里直接通过[0]拿 T。
- 这里拿到的 T 是包含泛型嵌套的。例如子类声明 extends CustomTypeHandler<List<List<Map<String, Person>>>>,这里会拿到 List<List<Map<String, Person>>>
- 如果想继续拿嵌套的内层泛型,可以继续调用 ParameterizedType#getActualTypeArguments
public abstract class CustomTypeHandler<T extends Object> {protected final Type _type;/*** 此方法实际由子类调用*/protected CustomTypeHandler() {Type superClass = getClass().getGenericSuperclass();// sanity check, should never happenif (superClass instanceof Class<?>) {throw new IllegalArgumentException("Internal error: TypeReference constructed without actual type information");}/** getActualTypeArguments 可能会存在多个泛型,例如 Map<K,V> 所以会返回 Type[] 数组* 根据 CustomTypeHandler 的约定,只能向 CustomTypeHandler 传递一个最外层 T,因此这里直接通过[0]拿 T。* 这里拿到的 T 是包含泛型嵌套的。例如子类声明 extends CustomTypeHandler<List<List<Map<String, Person>>>>,这里会拿到 List<List<Map<String, Person>>>* 如果想继续拿嵌套的内层泛型,可以继续调用 ParameterizedType#getActualTypeArguments*/_type = ((ParameterizedType) superClass).getActualTypeArguments()[0];}public Type getType() {return this._type;}
}
扩展阅读
- java Type 接口 https://blog.csdn.net/lvxiangan/article/details/94836504
相关文章:
![](https://img-blog.csdnimg.cn/img_convert/394077c6aa627081bcb19a2ffc872334.png)
获取泛型,泛型擦除,TypeReference 原理分析
说明 author blog.jellyfishmix.com / JellyfishMIX - githubLICENSE GPL-2.0 获取泛型,泛型擦除 下图中示例代码是一个工具类用于生成 csv 文件,需要拿到数据的类型,使用反射感知数据类型的字段,来填充表字段名。可以看到泛型…...
![](https://img-blog.csdnimg.cn/direct/5258b2ca838f48d5be951309184e249c.png)
springboot 3.x 之 集成rabbitmq实现动态发送消息给不同的队列
背景 实际项目中遇到针对不同类型的消息,发送消息到不同的队列,而且队列可能还不存在,需要动态创建,于是写了如下代码,实践发现没啥问题,这里分享下。 环境 springboot 3.2 JDK 17 rabbitMQ模型介绍 图片…...
![](https://www.ngui.cc/images/no-images.jpg)
C++ 代码实现鼠标右键注册菜单,一级目录和二级目录方法
最近做的一个项目, 在使用windows的时候,我希望在右键菜单中添加一个自定义的选项, 该选项下有我经常使用的多个程序快捷方式, 直接上代码 头文件 #pragma once #include <Windows.h> #include <iostream> #include <string> using namespace std; …...
![](https://img-blog.csdnimg.cn/direct/64d4dcf8752a4e9e83283f758be08596.png)
SQLite 3 优化批量数据存储操作---事务transaction机制
0、事务操作 事务的目的是为了保证数据的一致性和完整性。 事务(Transaction)具有以下四个标准属性,通常根据首字母缩写为 ACID: 原子性(Atomicity):确保工作单位内的所有操作都成功完成&…...
![](https://www.ngui.cc/images/no-images.jpg)
[程序员] 表达的能力
之前看CSDN的问答区,很多时候,感觉问题的描述所要表达的意思非常模糊,或者说描述不清。如果是想回答问题的人想回答问题,首先要搞清楚是什么问题,就需要再问问题主很多细节的东西。三来四去,才能搞清楚具体…...
![](https://img-blog.csdnimg.cn/direct/56774b7c6b2349c7b57bc4a8e5e2ae77.png)
rknn转换后精度差异很大,失真算子自纠
下面是添加了详细注释的优化代码: import cv2 import numpy as np import onnx import onnxruntime as rt from onnx import helper, shape_inferencedef get_all_node_names(model):"""获取模型中所有节点的名称。参数:model (onnx.ModelProto): O…...
![](https://img-blog.csdnimg.cn/direct/59e6d77fff0c4801aab33af7427e55aa.png)
【C语言】解决C语言报错:Stack Overflow
文章目录 简介什么是Stack OverflowStack Overflow的常见原因如何检测和调试Stack Overflow解决Stack Overflow的最佳实践详细实例解析示例1:递归调用过深示例2:分配过大的局部变量示例3:嵌套函数调用过多 进一步阅读和参考资料总结 简介 St…...
![](https://img-blog.csdnimg.cn/f95ddae62a4e43a68295601c723f92fb.gif#pic_center)
【滚动哈希 二分查找】1044. 最长重复子串
本文涉及知识点 滚动哈希 二分查找算法合集 LeetCode 1044. 最长重复子串 给你一个字符串 s ,考虑其所有 重复子串 :即 s 的(连续)子串,在 s 中出现 2 次或更多次。这些出现之间可能存在重叠。 返回 任意一个 可能具…...
![](https://www.ngui.cc/images/no-images.jpg)
webid、sec_poison_id、a1、web_session参数分析与算法实现
文章目录 1. 写在前面2. 参数分析3. 核心算法【🏠作者主页】:吴秋霖 【💼作者介绍】:擅长爬虫与JS加密逆向分析!Python领域优质创作者、CSDN博客专家、阿里云博客专家、华为云享专家。一路走来长期坚守并致力于Python与爬虫领域研究与开发工作! 【🌟作者推荐】:对爬…...
![](https://www.ngui.cc/images/no-images.jpg)
Qt|QWebSocket与Web进行通讯,实时接收语音流
实现功能主要思路:在网页端进行语音输入,PC机可以实时接收并播放语音流。 此时,Qt程序做客户端,Web端做服务器,使用QWebSocket进行通讯,实时播放接收的语音流。 功能实现 想要实现该功能,需要…...
![](https://img-blog.csdnimg.cn/img_convert/f4377cca15e431e57e3a02aef16dd819.jpeg)
「51媒体」电视台媒体邀约采访报道怎么做?
传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 电视台作为地方主流媒体,对于新闻报道有着严格的选题标准和报道流程。如果您希望电视台对某个会议或活动进行报道,可以按这样的方法来做: 1.明确活动信…...
![](https://img-blog.csdnimg.cn/direct/cb4e26753aea4c86879ab26923514e29.jpeg#pic_center)
Python提取PDF文本和图片,以及提前PDF页面中指定矩形区域的文本
前言 从PDF中提取内容能帮助我们获取文件中的信息,以便进行进一步的分析和处理。此外,在遇到类似项目时,提取出来的文本或图片也能再次利用。要在Python中通过代码提取PDF文件中的文本和图片,可以使用 Spire.PDF for Python 这个…...
![](https://img-blog.csdnimg.cn/direct/ed6f33ae7aa7476d87bb655e204a1707.jpeg#pic_center)
C#实现边缘锐化(图像处理)
在 C# 中进行图像的边缘锐化,可以通过卷积滤波器实现。边缘锐化的基本思想是通过卷积核(也称为滤波器或掩模)来增强图像中的边缘。我们可以使用一个简单的锐化核,例如: [ 0, -1, 0][-1, 5, -1][ 0, -1, 0]这个卷积核…...
![](https://img-blog.csdnimg.cn/direct/ed4f4d574d214dc5b8a9b00ab233611f.png)
ffmpeg windows系统详细教程
视频做预览时黑屏,但有声音问题解决方案。 需要将 .mp4编成H.264格式的.mp4 一般上传视频的站点,如YouTube、Vimeo 等,通常会在用户上传视频时自动对视频进行转码,以确保视频能够在各种设备和网络条件下流畅播放。这些网站通常…...
![](https://img-blog.csdnimg.cn/direct/5d18c32fed5a47bdb82bcdcffa2d371c.png)
【单片机】MSP430G2553单片机 Could not find MSP-FET430UIF on specified COM port 解决方案
文章目录 MSP430G2553开发板基础知识解决办法如何实施解决办法4步骤一步骤二步骤三 MSP430G2553开发板基础知识 MSP430G2553开发板如下图,上半部分就是UIF程序下载调试区域的硬件。个人觉得MSP430G2553开发板的这个部分没有做好硬件设计,导致很多系统兼…...
![](https://img-blog.csdnimg.cn/direct/65a87879838d4272bf143fb05f07e95a.png)
每日一题——力扣104. 二叉树的最大深度(举一反三+思想解读+逐步优化)四千字好文
一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 目录 我的写法 代码功能 代码结构 时间复杂度分析 空间复杂度分析 总结 我要更强 优化方法:迭代&…...
![](https://www.ngui.cc/images/no-images.jpg)
wpf textbox 有焦点 导致后台更新 前台不跟着改变
这个问题可能是由于 WPF 的数据绑定机制导致的。当 TextBox 有焦点时,它会独立于数据绑定进行更新,这可能会导致前台界面不能及时反映后台数据的变化。 1.使用 UpdateSourceTrigger 属性: 在数据绑定时,将 UpdateSourceTrigger 属性设置为 PropertyChanged。这样当 TextBox 的…...
![](https://img-blog.csdnimg.cn/direct/7cec52d5859b48268d084bf15c87669e.png)
数字化物资管理系统的未来:RFID技术的创新应用
在信息化和智能化不断发展的背景下,物资管理系统的数字化转型已成为各行各业关注的焦点。RFID技术作为一种先进的物联网技术,通过全面数字化实现物资信息的实时追踪和高效管理,为企业的物资管理提供了强有力的支持。 首先,RFID技…...
![](https://www.ngui.cc/images/no-images.jpg)
【docker】常用指令-表格整理
以下列出的指令是Docker中常用的命令,但并不是全部。Docker的指令非常丰富,可以根据具体的需求和场景选择合适的指令。同时,每个指令都有很多选项和参数可以使用,可以通过 docker COMMAND --help 来获取更详细的信息。 一、容器命…...
![](https://csdnimg.cn/release/blog_editor_html/release2.3.6/ckeditor/plugins/CsdnLink/icons/icon-default.png?t=N7T8)
洛谷——P2824 排序
题目来源:[HEOI2016/TJOI2016] 排序 - 洛谷https://www.luogu.com.cn/problem/P2824 问题思路 本文介绍一种二分答案的做法,时间复杂度为:(nm)*log(n)*log(n).本题存在nlog(n)的做法,然而其做法没有二分答案的做法通俗易懂. 默认读…...
![](https://img-blog.csdnimg.cn/img_convert/6995260d30a1d1700f2257aee71a7f6d.png)
echart在线图表demo下载直接运行
echart 全面的数据可视化图表解决方案 | 折线图、柱状图、饼图、散点图、水球图等各类图表展示 持续更新中 三色带下表题速度仪表盘 地图自定义图标 动态环形图饼状图 动态水波动圆形 多标题指针仪表盘 温度仪表盘带下标题 横向柱状图排名 环形饼状图 双折线趋势变化...
![](https://www.ngui.cc/images/no-images.jpg)
MLX5_SET_TO_ONES宏解析
看代码时,遇到一个非常复杂的宏MLX5_SET_TO_ONES,这个宏的主要作用是对特定的数据结构置位,宏的上下文如下: #define __mlx5_nullp(typ) ((struct mlx5_ifc_##typ##_bits *)0) #define __mlx5_bit_off(typ, fld) (offsetof(struc…...
![](https://img-blog.csdnimg.cn/direct/190b1196dac84bb28000ce36042fd826.png)
SQL Server入门-SSMS简单使用(2008R2版)-1
环境: win10,SQL Server 2008 R2 参考: SQL Server 新建数据库 - 菜鸟教程 https://www.cainiaoya.com/sqlserver/sql-server-create-db.html 第 2 课:编写 Transact-SQL | Microsoft Learn https://learn.microsoft.com/zh-cn/…...
![](https://www.ngui.cc/images/no-images.jpg)
高考专业抉择探索计算机专业的未来展望及适合人群
身份:一位正在面临人生重要抉择的高考生,一位计算机行业从业者 正文: 随着2024年高考落幕,我与数百万高三学生一样,又将面临人生中的重要抉择:选择大学专业。对于许多学生来说,计算机科学…...
![](https://www.ngui.cc/images/no-images.jpg)
windows安装spark
在 Windows 上安装 Spark 并进行配置需要一些步骤,包括安装必要的软件和配置环境变量。以下是详细的步骤指南: 步骤一:安装 Java 下载和安装 Java Development Kit (JDK) 到 Oracle JDK 下载页面 或 OpenJDK 下载页面 下载适合你系统的 JDK。…...
![](https://img-blog.csdnimg.cn/img_convert/c1aadea91d73de2a4960befb768214ca.png)
【信息学奥赛】CSP-J/S初赛03 计算机网络与编程语言分类
第1节 计算机网络基础 1.1 网络的定义 所谓计算机网络,就是利用通信线路和设备,把分布在不同地理位置上的多台计算机连 接起来。计算机网络是现代通信技术与计算机技术相结合的产物。 网络中计算机与计算机之间的通信依靠协议进行。协议是计算机收、发…...
![](https://img-blog.csdnimg.cn/direct/71704337e8484a16a0ef11c382be2643.png)
python20 函数的定及调用
函数的定及调用 函数是将一段实现功能的完整代码,使用函数名称进行封装,通过函数名称进行调用。以此达到一次编写,多次调用的目的 用 def 关键字来声明 函数 格式: def 函数名(参数列表):函数体[:return 返回值是可选的࿰…...
![](https://img-blog.csdnimg.cn/direct/55bd7a4c7f334d6d91dab2b4bf08d9b9.png)
【Android WebView】WebView基础
一、简介 WebView是一个基于webkit引擎、展现web页面的控件。Android的Webview在低版本和高版本采用了不同的webkit版本内核,4.4后直接使用了Chrome。 二、重要类 以WebView类为基础,WebSettings、WebViewClient、WebChromeClient为辅助共同完成安卓段加…...
![](https://img-blog.csdnimg.cn/direct/39482b016a464cdbb5ae4445ec947e3f.png)
Python酷库之旅-第三方库openpyxl(03)
目录 一、 openpyxl库的由来 1、背景 2、起源 3、发展 4、特点 4-1、支持.xlsx格式 4-2、读写Excel文件 4-3、操作单元格 4-4、创建和修改工作表 4-5、样式设置 4-6、图表和公式 4-7、支持数字和日期格式 二、openpyxl库的优缺点 1、优点 1-1、支持现代Excel格式…...
![](https://img-blog.csdnimg.cn/direct/755bb70fd0504ef38a00a7e074705bd2.png)
电脑丢失dll文件一键修复的方法有哪些?分析dll文件修复的多种策略
我们经常会遇到各种各样的问题,其中之一就是DLL文件的丢失。DLL文件(动态链接库)是操作系统和应用程序正常运行所必需的文件,当这些文件丢失或损坏时,可能会导致软件无法正常启动,甚至影响系统的稳定性。对…...
![](/images/no-images.jpg)
怀化网络推广收费标准/阿亮seo技术
第一步 使用influxd config > influxd.config生成默认配置文件 influxd.config。 第二步 然后修改influxd.config文件中的相关配置,保存。再用influxd -config influxd.config指定默认的配置文件启动服务。...
![](http://www.cqeis.com/imageRepository/ed15dafa-76f3-42be-9476-2a6f2ad1f253.jpg)
b2b网站怎么做推广/百度平台投诉人工电话
作者:诚恺科技来源:http://www.cqeis.com我们都知道,华为是以通信产品起家的,所以华为交换机、路由器、防火墙等网络通信产品在全球都处于领先地位,而华为交换机的型号及类别各不同,比如LI、SI、EI、HI等型…...
![](https://s1.51cto.com/images/20180423/1524481748835860.jpg?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
湖南网络科技有限公司/免费seo课程
3月15日,腾讯AI Lab第二届学术论坛在深圳举行,聚焦人工智能在医疗、游戏、多媒体内容、人机交互等四大领域的跨界研究与应用。全球30位顶级AI专家出席,对多项前沿研究成果进行了深入探讨与交流。腾讯AI Lab还宣布了2018三大核心战略ÿ…...
![](/images/no-images.jpg)
深圳p2p网站建设/西安seo推广公司
1.1 管道格式 将一个命令的输出作为另一个命令的输入,这个过程叫作管道连接(piping)。 command1 | command2 #管道连接格式Linux系统实际上会同时运行这两个命令,在 系统内部将它们连接起来。在第一个命令产生输出的同时&#x…...
![](https://img-blog.csdnimg.cn/img_convert/fd14d713bdcbccb1e6d112cfd5c9f25f.png)
什么网站可以做市场分析呢/谷歌优化推广
1)实验平台:正点原子水星 STM32F4/F7 开发板2)摘自《STM32F7 开发指南(HAL 库版)》关注官方微信号公众号,获取更多资料:正点原子http://weixin.qq.com/r/hEhUTLbEdesKrfIv9x2W (二维码自动识别)第十六章 电容触摸按键实…...
![](http://img.watchstor.com/uploadimg/20110331/1412553.jpg)
安徽网站建设公司/百度官网登录入口手机版
VNXe会给存储系统带来颠覆性变革么? 2011-03-31 弯曲评论 冬瓜头 摘要:存储巨头EMC最近发布了Clariion和Celerra联合整容之后的VNX以及里程碑VNXe产品,对这两个系列的产品的规格细节功能等就不再做过多介绍了。标签:VNXe 存储系…...