java方法返回类型不是实际类型

时间:2018-06-09 03:41:35

标签: java methods reflection return-type

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,而不是TypeBTypeBTypeA的子类。

如何获取方法的实际返回类型?它是TypeB,而不是TypeA

更新

我用过

Method[] methods = Bar.class.getDeclaredMethods();

然后遍历这些方法。该方法返回超类。验证getDeclaredMethod(&#34; hello&#34;)确实返回子类类型。他们为什么不同?

1 个答案:

答案 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表示它不是感兴趣的方法)。