Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java method return type is not actual type

java method return type is not the actual type. For example,

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 is TypeA, not TypeB. TypeB is a subclass of TypeA.

How to get the actual return type of the method? It is TypeB, not TypeA.

UPDATE

I used

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

and then iterate through the methods. The method returns the superclass. Verified that getDeclaredMethod("hello") do return the subclass type. Why are they different?

like image 501
eastwater Avatar asked Jun 09 '18 03:06

eastwater


1 Answers

If you iterate through all declared methods with getDeclaredMethods() you will find two methods of similar signature:

  • TypeB hello() (this is the one you expected)
  • TypeA hello() (this is the one you talk of)

A look into the byte code reveals following entries:

public hello()Ltest/TypeB;

//... the bytecode for your method

public synthetic bridge hello()Ltest/TypeA;

//... bytecode that delegates to hello()Ltest/TypeB

This is an effect of the javac compiler, which introduces a synthetic bridging method TypeA hello() which only delegates to TypeB hello().

The reason is that only a method of same signature can be called virtually. Since the interfaces signature is TypeA hello() any call to the interface will call TypeA hello() in the implementation. Yet your class Bar does not contain this method, but a replacement TypeB hello(). To resolve this issue javac chose to bridge the method (delegate it to the replacement). I think this will save them a lot of work at runtime.

So your problem does not occur from the method returning the wrong type, but your code returning the wrong method. If you iterate the methods, call isSynthetic() on them (true means that it is not the method of interest).

like image 112
CoronA Avatar answered Oct 30 '22 18:10

CoronA