你好,我是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 {
@Test
public void fun() {
List<Integer> numbers = new ArrayList<>();
numbers.add(18);
List newNumbers = numbers;
newNumbers.add("YourBatman");
System.out.println(numbers);
}
@Test
public 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的泛型是伪泛型,编译后泛型类型都会被擦除。
记住结论的同时,通过本文对比了多个反编译器的结果亦可得到两条基本的常识:
- 像IDEA内置的
Java Bytecode Decompiler
以及jadx
这种比较新(还在持续迭代)的工具,称作智能反编译器更为合适:它能重排序代码,并且“保留”住泛型类型,方便开发者阅读 - 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