Java方法调用重载逻辑

对于以下代码,为什么要打印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.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类已知,因此调用带参数A的方法。 所以是的,它是静态决定的。

这是为了避免含糊不清。 你的B也是A – 但是这两种方法不能同时被调用。

BA的子类。 由于您实例化B ,但将其分配给变量类型A ,所有B细节都将“丢失”,因此call(a)将被调度到call(A, a)并打印’A’。