Java片段输出未被理解,可能与多态性有关

l0r*_*c10 4 java polymorphism

我想知道为什么这一点Java会产生2而不是3:

public class Test {
    private static class A {
        int f(A a) {
            return 1;
        }
    }
    private static class B extends A {
        int f(A a) {
            return 2;
        }
        int f(B b) {
            return 3;
        }
    }

    public static void main(String[] astrArgs) {
        A ab = new B();
        B b = new B();

        System.out.println( ab.f(b) );  
    }
}
Run Code Online (Sandbox Code Playgroud)

我在一个测试问题中遇到过这个问题,并且无法得到它背后的逻辑.

Jon*_*eet 8

编译时的类型ab就是A.因此,当编译器看到此表达式时:

ab.f(b)
Run Code Online (Sandbox Code Playgroud)

... 它只考虑在A其上声明的方法签名及其超类(仅Object在本例中).

因此,编译器决定使用签名调用该方法f(A a).

现在,在执行时,VM 根据方法调用的目标的执行时类型选择执行该签名的哪个实现,即B.

B覆盖f(A a),以便调用覆盖实现 - 并返回2.

基本上,在编译时确定重载,以根据调用目标和参数的编译时类型确定要调用的方法签名,并在执行时确定重写以确定实际的实现基于目标对象的执行时类型执行.