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

Sun*_*day 6 java reflection methods 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();
Run Code Online (Sandbox Code Playgroud)

returnType是TypeA,不是TypeB. TypeB是.的子类TypeA.

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

UPDATE

我用了

Method[] methods = Bar.class.getDeclaredMethods();
Run Code Online (Sandbox Code Playgroud)

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

Cor*_*onA 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
Run Code Online (Sandbox Code Playgroud)

这是javac编译器的一个效果,它引入了一个TypeA hello()只委托给它的合成桥接方法TypeB hello().

原因是只能虚拟地调用相同签名的方法.由于接口签名是对接口的TypeA hello()任何调用都会TypeA hello()在执行中调用.然而你的班级Bar不包含这种方法,而是替代方法TypeB hello().为解决此问题,javac选择桥接该方法(将其委托给替换方法).我认为这会在运行时为他们节省大量的工作.

所以你的问题不会从返回错误类型的方法发生,但你的代码返回错误的方法.如果迭代方法,请调用isSynthetic()它们(true表示它不是感兴趣的方法).