java.lang.Class::getDeclaredMethods 文档中的一个奇怪的子句

zom*_*rot 5 java reflection interface

来自 java.lang.Class::getDeclaredMethods 的文档:

返回一个包含 Method 对象的数组,该对象反映了此 Class 对象表示的类或接口的所有已声明方法,包括公共方法、受保护方法、默认(包)访问方法和私有方法,但不包括继承的方法。声明的方法可能包括类或接口源中没有的方法,包括桥接方法和编译器添加的其他合成方法。 如果此 Class 对象表示一个类或接口,该类或接口具有多个具有相同名称和参数类型但返回类型不同的声明方法,则返回的数组对于每个此类方法都有一个 Method 对象...

AFAIK java 不允许类或接口的方法仅因返回类型而不同(返回类型不是函数签名的一部分),那么这是如何发生的呢?

Tur*_*g85 4

为了理解为什么这是可能的,我们需要理解 Java 中实际上有两个世界:由 JLS 管理的 Java 语言世界和由 JVM 规范管理的 Java 虚拟机世界。

这些世界并不总是 1:1 匹配。你找到了一个例子。另一个例子是泛型。由于类型擦除(oracle.com),类型通过编译器被替换为上限,因此所有类型信息在运行时都会丢失。.class这就是为什么我们不能调用通用参数的原因T

通常作为程序员,我们只与 Java 语言交互,编译器负责将代码转换为在 JVM 上执行的字节码。另一方面,反射允许我们在运行时与对象交互。就这样,我们得以一睹这个世界的风采。在这种特定情况下,JVM 规范 $4.7.9.1 ( docs.oracle.com)指出:

...

方法签名对有关(可能是通用的)方法声明的类型信息进行编码。它描述了该方法的任何类型参数;任何形式参数的(可能是参数化的)类型;(可能是参数化的)返回类型,如果有的话;以及方法的 throws 子句中声明的任何异常的类型。

MethodSignature:
  [TypeParameters] ( {JavaTypeSignature} ) Result {ThrowsSignature}

Result:
  JavaTypeSignature
  VoidDescriptor

ThrowsSignature:
  ^ ClassTypeSignature
  ^ TypeVariableSignature
Run Code Online (Sandbox Code Playgroud)

...