如何查看Java编译器隐式生成的内部代码?反编译看不到默认构造函数原因
反编译看不到自动生成的默认构造函数的原因
你遇到的情况不是构造函数不存在,是常用反编译工具的默认优化逻辑导致的:
Java规范里明确,当类没有显式定义任何构造函数时,编译器必须自动生成一个无参的默认构造函数,这个构造函数会默认调用父类的无参构造函数,和你手动写空实现的同访问级别无参构造函数功能完全一致。
大部分反编译工具(比如JD-GUI、Luyten等)为了让输出结果尽可能贴近用户原始编写的源码,会默认把这类符合规范的隐式生成的默认构造函数过滤掉,不会在反编译结果里展示。
查看编译器隐式生成代码的方法
有几种可靠的方案可以验证、查看这些隐式生成的内容:
用JDK自带的javap工具查看字节码
javap是JDK原生的字节码解析工具,不会做任何源码还原的优化过滤,能直接展示class文件里的真实内容。编译得到Test.class后,在命令行执行:javap -v Test输出内容里可以明确找到自动生成的默认构造函数的字节码信息,示例输出片段如下:
Test(); descriptor: ()V flags: (0x0000) Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // 调用父类Object的<init>方法,也就是super() 4: return调整反编译工具的配置
多数主流反编译工具都支持关闭隐藏合成构造函数的选项,比如Luyten可以在设置中取消勾选「Hide synthetic default constructors」,之后再反编译就能看到隐式生成的默认构造函数了。用反射验证构造函数存在
可以通过Java反射API直接读取类的构造函数列表,代码示例如下:import java.lang.reflect.Constructor; public class VerifyConstructor { public static void main(String[] args) { Constructor<?>[] allConstructors = Test.class.getDeclaredConstructors(); for (Constructor<?> c : allConstructors) { System.out.println("找到构造函数:" + c); } } }运行后会输出
找到构造函数:Test(),直接证明默认构造函数确实存在于类结构中。
内容的提问来源于stack exchange,提问作者MUSTAFA HASAN
相关产品推荐
相关产品推荐

