Java中的反射与继承
我有以下代码片段:
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());
}
}
这段代码返回java.lang.Number
,这对我来说非常奇怪,因为基类的getX
方法返回java.lang.Integer
。最有趣的是,如果BaseClass
实现了接口,则返回的类型是java。整型。。。这是正常的行为吗
# 1 楼答案
这是包含泛型的Java framework 1.6的一个函数。Integer和Double是数字的子类型
# 2 楼答案
是的,这是正常的:
Integer
是Number
的一个子类InheritedClass
实现了Interface
,所以使用了来自该接口的getX
返回类型,即Number
李># 3 楼答案
以下是我认为会发生的事情
通过同时扩展
BaseClass
和实现Interface
,子类承诺提供两种getX()
方法:因为不能重载返回类型,所以只能有一个方法。此外,它的返回类型必须是
Number
,而不是Integer
(因为可以将后者转换为前者,但不能将后者转换为前者)为了协调上述所有内容,编译器会在
InheritedClass
中自动生成以下方法:如您所见,它在
Interface
中具有方法的签名,但会自动委托给BaseClass
中的方法(带有隐式的向上转换)这个自动生成的方法就是反射代码所采用的方法
# 4 楼答案
JLS的相关章节为§8.4.8.4:
我们在这里考虑的两种方法是:
public Integer getX();
public abstract Number getX();
由于
BaseClass.getX
不是abstract
,并且它是return-type-substitutable(Integer
是Number
的子类),因此Interface.getX
选择BaseClass.getX
来覆盖Interface.getX
这很奇怪,因为这不是你看到的结果。但是,如果您试图在
InheritedClass
中定义方法public Number getX()
,您将收到一个错误,这与上述内容一致