001. 为啥用IDEA反编译没有擦除泛型?

news/2024/11/14 13:10:36/

在这里插入图片描述

你好,我是YourBatman:一个俗人,贪财好色。

📚前言

Java泛型是进阶高级开发必备技能之一,了解实现泛型的基本原理,有助于写出更优质的代码。

众所周知,Java是伪泛型,是通过类型擦除(Type Erasure)来实现的。为了“查看/证明”Java对泛型类型的擦除,我们常常通过反编译的手段实现。Intellij IDEA作为Java开发主流IDE,它内置的反编译功能是最为常用的反编译工具。

但是,你会发现,IDEA的反编译竟没有擦除泛型。

✍正文

如下代码:

/*** 在此处添加备注信息** @author YourBatman's home page. <a href=https://yourbatman.cn>https://yourbatman.cn</a>* @author YourBatman. <a href=mailto:yourbatman@aliyun.com>Send email to me</a>* @author wechat:fsx641385712* @since 0.0.1*/
public class Tester {@Testpublic void fun() {List<Integer> numbers = new ArrayList<>();numbers.add(18);List newNumbers = numbers;newNumbers.add("YourBatman");System.out.println(numbers);}@Testpublic void fun1() {List<Integer> intList = new ArrayList<>();List<String> stringList = new ArrayList<>();System.out.println(intList.getClass() == stringList.getClass());}}

我们借助IDEA的反编译后的内容:找到需要反编译的.class文件
在这里插入图片描述
双击即可查看:
在这里插入图片描述
我的天,泛型类型不应该被擦除了吗,为毛还在?IDEA的反编译工具难道有bug?

🌈尝试其它反编译工具

IDEA最初内置的是著名的JD-GUI反编译插件,从2016年起改为自研的反编译插件Java Bytecode Decompiler,一直沿用至今:
在这里插入图片描述
为了验证此问题,我计划多试试几款反编译工具。

🚀jd-gui

下载地址:https://github.com/java-decompiler/jd-gui/releases
在这里插入图片描述
尴尬的是,双击打不开:在这里插入图片描述
无奈。在虚拟机里启了个Windows 11来跑:
在这里插入图片描述
结论:没有擦除泛型类型。和IDEA不同的是它反编译出来的结果更“原始”一丢丢

🚀jadx

下载地址:https://github.com/skylot/jadx/releases
在这里插入图片描述
同样的Windows 11上运行进行反编译:
在这里插入图片描述
结论:没有擦除泛型类型。结果不说和IDEA差不多,也是一模一样。

🚀JAD

下载地址:https://varaneckas.com/jad
在这里插入图片描述
由于我的本是基于Apple Silicon芯片的,所以只能继续在Windows上执行了:
在这里插入图片描述
结论:泛型类型被擦除了

🚀Beyond Compare 4

Beyond Compare的主业是做文件比较,其实它也可以Java反编译。只需在https://www.scootersoftware.com/download.php?zz=moreformats下载所需插件:
在这里插入图片描述
使用Beyond Compare 4进行反编译:
在这里插入图片描述
结论:泛型类型被擦除了。Beyond Compare 4的反编译基于Jad,因此效果和Jad一模一样

🚀javap -c

使用最底层的javap -c进行反编译:
在这里插入图片描述
结论:泛型类型被擦除了

🍞总结

有些擦除了但有些没有擦除泛型类型,到底该信谁呢?当然是无条件相信javap -c,因为一切反编译操作都基于它。so结论是:Java的泛型是伪泛型,编译后泛型类型都会被擦除。

记住结论的同时,通过本文对比了多个反编译器的结果亦可得到两条基本的常识:

  1. 像IDEA内置的Java Bytecode Decompiler以及jadx这种比较新(还在持续迭代)的工具,称作智能反编译器更为合适:它能重排序代码,并且“保留”住泛型类型,方便开发者阅读
  2. Java泛型引入至今已有近20年,“伪泛型”已被认为是所有开发者的共识,没有必要再在反编译后体现出来反倒大大降低了可读性。像Jad这种“上古”时期的反编译器,依旧原汁原味

推荐阅读

  • IntelliJ IDEA 2022.3正式发布,配置云同步&支持Redis好用到炸

在这里插入图片描述
本专栏源代码库:https://github.com/yourbatman/yourbatman-999-question

  • 个人博客:https://yourbatman.cn
  • 程序员网盘:https://wangpan.yourbatman.cn
  • 女娲工程:https://start.yourbatman.cn
  • 更多专栏:https://yourbatman.cn/columns |或| 公号后台回复“专栏列表”获取全部小而美的原创技术专栏

我是YourBatman,一个俗人,贪财好色。历经过延期毕业、卖保险、送外卖的大龄程序员,《梦幻西游》骨灰玩家;龙珠迷、火影迷。前大厂资深技术专家,现资深领域建模专家、Java架构师;高质量代码、DDD面向对象设计布道师;Spring开源贡献者,CSDN博客之星年度Top 10,出版书籍《Spring奇淫巧技》&《领域建模之面向对象程序设计》进行时。wx:yourbatman-u


http://www.ppmy.cn/news/83890.html

相关文章

《计算之魂》引子

了解计算机基本原理的读者朋友可以跳过这个引子直接阅读第 1 章&#xff0c;因为本书其他章节并不依赖本章内容。不过&#xff0c;如果你愿意花上半小时读一读这一部分&#xff0c;相信会从数学和哲学层面对计算机以及计算的本质有更深刻的理解。 0.1 什么是计算机 如果你有…

【每日一题Day214】LC1080根到叶路径上的不足节点 | 递归

根到叶路径上的不足节点【LC1080】 给你二叉树的根节点 root 和一个整数 limit &#xff0c;请你同时删除树中所有 不足节点 &#xff0c;并返回最终二叉树的根节点。 假如通过节点 node 的每种可能的 “根-叶” 路径上值的总和全都小于给定的 limit&#xff0c;则该节点被称之…

NumPy

目录 1、NumPy简介 2、利用元组、列表创建多维数组 3、数组索引 4、数组裁切 4.1、一维数组操作 4.2、二维数组操作 5、数据类型 6、副本/视图 7、数组形状 8、数组重塑 9、多维数组的迭代 10、数组连接 10.1、使用concatenate() 函数进行数组连接 10.2、使用堆栈…

开发者关系工程师如何帮助开发者在Sui上构建

近期&#xff0c;我们与Sui开发者关系负责人Brian Hennessey-Hsien进行了对话&#xff0c;就Sui上的开源、去中心化和开发者成就等话题展开讨论。 日前&#xff0c;我们采访了Sui基金会的开发者关系负责人Brian Hennessey-Hsieh&#xff0c;共同探讨了其对于Web3中开发者发展历…

SpringBoot 结合 MyBatis-plus 进行逻辑删除

一 、逻辑删除的概念 逻辑删除不会在数据库中删除数据&#xff0c;只是通过一个字段用来标识被删除的记录&#xff0c;数据仍然保存在数据库中。在实际的工作当中&#xff0c;因为数据非常重要&#xff0c;为了防止因用户误操作删除数据后无法恢复的问题&#xff0c;我们通常不…

Linux系统驱动跟裸机驱动的区别

区别指示 Linux系统驱动和裸机驱动的主要区别在于它们运行的环境和依赖不同。 Linux系统驱动&#xff08;Linux Device Driver&#xff09;&#xff1a; Linux系统驱动是在Linux操作系统环境下运行的。这类驱动通常依赖于Linux内核提供的API和服务&#xff08;如内存管理、任务…

机器人的运动范围:DFS

Problem: 剑指 Offer 13. 机器人的运动范围 文章目录 思路解题方法复杂度Code 思路 首先定义好地图&#xff0c;上下左右四个方向也就是{{1,0},{0,1},{-1,0},{0,-1}}&#xff0c;然后我们另外定义一个方法来判断题目要求的下标位数和是否大于k&#xff0c; boolean check(int x…

【vue3】 实现 公共搜索组件,在当前页搜索的路由跳转不能改变当前值的操作,使用bus / event-emitter 派发器

一、安装 bus 插件 cnpm install --save event-emitter 二、创建 bus.ts 文件 1、在utils下创建bus.ts 2、bus.ts 代码如下 import ee from event-emitter export default ee() 三、页面使用 1、搜索的公用组件页面&#xff0c;search.vue <el-input v-model.trim&qu…