java方法返回类型不是实际类型。例如,
public interface Foo<X extends TypeA> {
public X hello();
}
public class Bar implements Foo<TypeB> {
@Override
public TypeB hello() {
...
}
}
Method method = Bar.class.getDeclaredMethod("hello");
Class returnType = method.getReturnType();
returnType为TypeA
,而不是TypeB
。 TypeB
是TypeA
的子类。
如何获取方法的实际返回类型?它是TypeB
,而不是TypeA
。
我用过
Method[] methods = Bar.class.getDeclaredMethods();
然后遍历这些方法。该方法返回超类。验证getDeclaredMethod(&#34; hello&#34;)确实返回子类类型。他们为什么不同?
答案 0 :(得分:6)
如果使用getDeclaredMethods()
遍历所有声明的方法,您会发现两种类似签名的方法:
TypeB hello()
(这是您期望的那个)TypeA hello()
(这是你谈到的那个)查看字节代码可以看到以下条目:
public hello()Ltest/TypeB;
//... the bytecode for your method
public synthetic bridge hello()Ltest/TypeA;
//... bytecode that delegates to hello()Ltest/TypeB
这是javac编译器的一种效果,它引入了一种合成桥接方法TypeA hello()
,它只委托给TypeB hello()
。
原因是只能虚拟地调用相同签名的方法。由于接口签名为TypeA hello()
,因此对接口的任何调用都将在实现中调用TypeA hello()
。但是,您的班级Bar
不包含此方法,而是替换TypeB hello()
。为解决此问题,javac选择桥接该方法(将其委托给替换方法)。我认为这会在运行时节省大量的工作。
因此,返回错误类型的方法不会出现问题,但代码返回错误的方法。如果迭代方法,请对它们调用isSynthetic()
(true表示它不是感兴趣的方法)。