使用IDEA反编译没有擦除泛型的原因解析

 更新时间:2023年05月22日 15:28:15   作者:YourBatman  
Java泛型引入至今已有近20年,“伪泛型”已被认为是所有开发者的共识,没有必要再在反编译后体现出来反倒大大降低了可读性,这篇文章主要介绍了使用IDEA反编译没有擦除泛型的原因解析,需要的朋友可以参考下

📚前言

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

到此这篇关于为啥用IDEA反编译没有擦除泛型的文章就介绍到这了,更多相关IDEA反编译没有擦除泛型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot开发OAuth2认证授权与资源服务器操作

    Springboot开发OAuth2认证授权与资源服务器操作

    这篇文章主要介绍了Springboot开发OAuth2认证授权与资源服务器操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    这篇文章主要介绍了IntelliJ IDEA下自动生成Hibernate映射文件以及实体类,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-11-11
  • Java微信公众号模板消息推送功能实例代码

    Java微信公众号模板消息推送功能实例代码

    这篇文章主要介绍了Java微信公众号模板消息推送功能的相关资料,包括了公众号开发者平台的参数获取、微信发送接口的实际调用、消息发送的util类、示例模板以及接口调用的示例,需要的朋友可以参考下
    2025-05-05
  • MyBatis中的XML实现和动态SQL实现示例详解

    MyBatis中的XML实现和动态SQL实现示例详解

    这篇文章主要介绍了MyBatis中的XML实现和动态SQL实现,我们可以将XML中重复出现的内容提取出来放到sql标签中,当需要用到sql标签中的内容时,用include标签将sql标签中的内容引进来即可,感兴趣的朋友跟随小编一起看看吧
    2024-02-02
  • Spring Modulith模块化单体应用的概念和优势

    Spring Modulith模块化单体应用的概念和优势

    本文将深入探讨Spring Modulith的核心概念、实现方式以及最佳实践,帮助开发者构建易于维护且具有良好扩展性的现代Java应用,感兴趣的朋友一起看看吧
    2025-09-09
  • shardingjdbc之配置druid数据库连接池过程

    shardingjdbc之配置druid数据库连接池过程

    这篇文章主要介绍了shardingjdbc之配置druid数据库连接池过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-03-03
  • SpringBoot2.1 RESTful API项目脚手架(种子)项目

    SpringBoot2.1 RESTful API项目脚手架(种子)项目

    这篇文章主要介绍了SpringBoot2.1 RESTful API项目脚手架(种子)项目,用于搭建RESTful API工程的脚手架,只需三分钟你就可以开始编写业务代码,不再烦恼于构建项目与风格统一,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Java多线程工具篇BlockingQueue的详解

    Java多线程工具篇BlockingQueue的详解

    今天小编就为大家分享一篇关于Java多线程工具篇BlockingQueue的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java 给图片和动图添加水印的方法

    Java 给图片和动图添加水印的方法

    本篇文章主要介绍了Java 给图片和动图添加水印的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-04-04
  • Java操作PDF文件实现签订电子合同详细教程

    Java操作PDF文件实现签订电子合同详细教程

    这篇文章主要介绍了如何在PDF中加入电子签章与电子签名的过程,包括编写Word文件、生成PDF、为PDF格式做表单、为表单赋值、生成文档以及上传到OBS中的步骤,需要的朋友可以参考下
    2025-01-01

最新评论