关于Class.getDeclaredMethod的Javadoc描述的疑问
为什么Class.getDeclaredMethods的Javadoc会提到“同名同参数不同返回值的方法”?
你这个问题问到点子上了——毕竟我们从学Java开始就被告知:方法重载只看方法名和参数列表,返回类型不算在内,Java编译器根本不允许同一个类里出现同名、同参数类型但返回值不同的方法。那Javadoc这段描述到底是什么意思?
核心原因其实是:Java语言规范不允许,但JVM的类文件格式允许。
具体来说:
- Java层面的方法签名(用来判断重载的依据)只包含方法名称和参数类型;
- 但JVM层面的方法签名是包含返回类型的——也就是说,类文件里完全可以存在两个方法,它们的名字、参数列表完全一样,只有返回类型不同,JVM是可以加载并执行这样的类的。
那这种类怎么来的?肯定不是用普通Java编译器编译出来的,常见的场景有:
- 通过字节码操作工具(比如ASM、ByteBuddy、CGLIB)手动生成类文件,直接往里面添加这种方法;
- 通过JNI(Java Native Interface)生成的本地方法,可能会出现这种情况;
- 某些老旧的第三方库或者特殊工具生成的类,可能包含这类方法。
而Java的反射API是直接和JVM交互的,它的职责是如实返回类中实际存在的所有方法——不管这个类是不是符合Java语言规范。所以当你用getDeclaredMethods()去获取这类特殊类的方法时,就会得到包含这些“违反Java语法”的方法数组,Javadoc这段描述就是提前说明这种特殊情况。
举个简单的例子:如果你用ASM写一段字节码,生成一个类,里面有两个public int foo()和public String foo()的方法,JVM是能加载这个类的,反射也能拿到这两个Method对象,只是你没法用Java代码直接调用它们(因为Java编译器会报错)。
内容的提问来源于stack exchange,提问作者Dean Xu
相关产品推荐
相关产品推荐

