I have the following fragment of code:
class BaseClass {
public Integer getX() {
return 5;
}
}
class InheritedClass extends BaseClass implements Interface {
}
interface Interface {
public Number getX();
}
public class Test5 {
public static void main(String[] args) throws Exception {
System.out.println(InheritedClass.class.getMethod("getX").getReturnType());
}
}
this code returns java.lang.Number, which is very strange to me, because BaseClass's getX method returns java.lang.Integer. And the most interesting is that if BaseClass implements Interface, the returned type is java.lang.Integer... Is this a normal behaviour?
Here is what I think happens.
By simultaneously extending BaseClass and implementing Interface, the subclass promises to provide two getX() methods:
public Integer getX();
public Number getX();
Since you can't overload on return type, there can only be one method. Furthermore, its return type has to be Number rather than Integer (since you can cast the latter to the former, but not vice versa).
To reconcile all of the above, the compiler automatically generates the following method in InheritedClass:
public java.lang.Number getX();
Code:
0: aload_0
1: invokevirtual #22 // Method getX:()Ljava/lang/Integer;
4: areturn
As you can see, it has the signature of the method in Interface, but automatically delegates to the method in BaseClass (with an implicit upcast).
This automatically-generated method is what your reflection code is picking up.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With