Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reflection and inheritance in Java

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?

like image 894
Georgi Georgiev Avatar asked Sep 01 '26 03:09

Georgi Georgiev


1 Answers

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.

like image 163
NPE Avatar answered Sep 03 '26 18:09

NPE



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!