Java方法调用重载逻辑
对于以下代码,为什么打印A、B?我希望它能打印B,B。 另外,JVM执行的方法调用是动态评估还是静态评估Java方法调用重载逻辑,java,jvm,overloading,Java,Jvm,Overloading,对于以下代码,为什么打印A、B?我希望它能打印B,B。 另外,JVM执行的方法调用是动态评估还是静态评估 public class Main { class A { } class B extends A { } public void call(A a) { System.out.println("I'm A"); } public void call(B a) { System.out.prin
public class Main {
class A {
}
class B extends A {
}
public void call(A a) {
System.out.println("I'm A");
}
public void call(B a) {
System.out.println("I'm B");
}
public static void main(String[] args) {
Main m = new Main();
m.runTest();
}
void runTest() {
A a = new B();
B b = new B();
call(a);
call(b);
}
}
重载由编译器静态确定。重写在执行时完成,但这不是一个因素
a
的静态类型是a,因此第一个方法调用被解析为call(a)
,因为您的对象是通过其类型a
知道的,此时将调用带有参数a
的方法。是的,它是静态确定的
这是为了避免歧义。您的
B
也是A
——但不能同时调用这两个方法。B
是A
的子类。由于您实例化了aB
,但将其分配给了类型为a
的变量,所有B
细节都将“丢失”,因此call(a)
将被分派到call(a,a)
并打印“a”。谢谢,那么什么是动态计算的呢?@Maxim Veksler:Overriding——这是由目标对象的实际类型而不是编译时类型决定的。这有点误导。名为a
的对象仍然保留“其B
的所有细节”-例如,调用a.getClass().getSimpleName()
将返回“B”。正如Jon指出的,重载是由编译时引用的类型决定的。编译器在此上下文中不“知道”a
实际上是B
的实例,因此它编译对call(a)
方法的调用。但是a
仍然是B
的一个实例。