时间:2016-04-18 17:56:26

标签: java reflection

我知道,至少已有one question on this topic。但我想再问一遍,因为这是我在javadoc of Class#getDeclaredMethod(...)中发现的:

  

如果在a中声明了多个具有相同参数类型的方法   class,其中一个方法的返回类型更多   特定于任何其他方法,返回该方法;除此以外   其中一种方法是任意选择的。

因此,java中反射的开发人员认为这种情况很可能,毕竟这可能是可能的吗?或者它可能只是被弃用了?

1 个答案:

答案 0 :(得分:9)

JVM字节码格式允许声明具有相同名称和相同参数类型的多个方法,只要返回类型不同,尽管Java 语言不允许这样做。这意味着a)其他JVM语言可以使用它,b)它可以用于特殊的"编译器魔术"语言特色。

最常见的是,编译器在处理泛型时会发出多个具有相同名称和相同参数类型的方法。 JVM方法查找依赖于匹配的整个签名,而不仅仅是参数类型。因此,编译器必须发出所谓的 Raven.Server.exe -restore -src "C:\Datazen\Backups\datazen-201604181-93fa5e38" -dest "C:\Program Files\Datazen Enterprise Server\data" esentutl /d Data\Data Datazen.Server.Service /console /shutdown net start datazen net start datazenrenderingservice net start datazendata 方法,这些方法可以在签名方面覆盖或隐藏其他方法。考虑这个例子:

bridge

interface Foo<T> { T foo(); // desc: ()Ljava/lang/Object; void bar(T value); // desc: (Ljava/lang/Object;)V Object baz(); // desc: ()Ljava/lang/Object; } class StringFoo implements Foo<String> { @Override public String foo() { ... } // desc: ()Ljava/lang/String; // ! @Override public void bar(String value) { ... } // desc: (Ljava/lang/String;)V // ! @Override public String baz() { ... } // desc: ()Ljava/lang/String; // ! } 类需要三个额外的桥接方法来实际覆盖接口方法,具有相同的StringFoo

desc

伪修饰符class StringFoo implements Foo<String> { public String foo() { ... } public /* synthetic bridge */ Object foo() // desc: ()Ljava/lang/Object; { return /* String */ foo(); // statically linked to String foo() } public void bar(String value) { ... } public /* synthetic bridge */ void bar(Object value) // desc: (Ljava/lang/Object;) { return bar((String) value); } public String baz() { ... } public /* synthetic bridge */ Object baz() // desc: ()Ljava/lang/Object; { return /* String */ baz(); // statically linked to String baz() } } 是两个JVM访问标志,仅供编译器用于在字节码中标记自动生成的方法

synthetic bridge方法返回所有声明的方法 - 包括合成桥接方法。因此,Class#getDeclaredMethods必须选择一个实际实现。