How does the compiler decide between overloading and overriding?(编译器如何决定是重载还是重写?)
问题描述
class A {
public void doSomething(float f) {
//print "in A"
}
}
class B extends A {
public void doSomething(int i) {
// print "in B"
}
public static void main(String[] args) {
A a = new B();
a.doSomething(10);
}
}
编译器首先检查doSomething()
是否存在于类A中,一旦确认,则在运行时检查对象类型并执行相应的方法,即应该执行类B的doSomething()
,而执行类A
的doSomething()
。
如果两个方法相同,则只执行B
doSomething()
类。
编译器如何确定某个方法被重写,从而由JVM处理?
推荐答案
简单地说:
- 编译器选择要调用的方法的签名
- 运行库选择将运行编译器选择的签名的哪个实现
在步骤1中,编译器查看调用该方法的对象的声明类型,以及参数类型,这意味着:
- 编译器只知道
a
是A
(";声明类型,又称静态类型);因此它只能搜索A
中的方法或A
继承的方法。这意味着编译器甚至不会在示例中的类B
中搜索doSomething
。 - 它查看参数的数据类型以在重载中解析一个方法。在您的示例中,这不是必需的,因为只有一个
doSomething
方法(带有float
参数的方法)
基于以上情况,编译器只能得出将运行的doSomething(float)
的结论。您可以将其视为编译器的选定方法签名是一成不变的,运行库无法更改这一点。
doSomething(float)
),它唯一需要做的就是选择将调用该签名的哪个实现。为此,它查看了示例中的实际对象类型(创建的对象)new B()
。然后,它将在B
、中运行实现(如果被重写),或者在树中搜索该签名的任何被重写的实现,直到它到达A
中继承的实现。由于B
不重写doSomething(float)
,因此从A
继承的实现A.doSomething(float)
运行。
这篇关于编译器如何决定是重载还是重写?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!