遮蔽静态方法

use*_*383 5 java static

我正在阅读有关静态方法的阴影,但我不明白一件事,即编译器如何选择要运行的方法。假设我有3个班级。

public static class A {
        public static int test() {
            return 1;
        }
    }

    public static class B extends A {
        public static int test() {
            return 2;
        }
    }

    public static class C extends B {
        public static int test() {
            return 3;
        }
    }
Run Code Online (Sandbox Code Playgroud)

显然,当我调用方法时,A.test() B.test() C.test()我会得到结果1 2 3

但是,如果我从实例中调用它(我知道是不好的做法),那么当此代码时:

C c = new C();
System.out.println(c.test());
Run Code Online (Sandbox Code Playgroud)

会按照我的预期打印3,但是当我这样做时

B b = c;
System.out.println(b.test());
Run Code Online (Sandbox Code Playgroud)

那么我的输出将为2。这对于我来说是令人惊讶的,因为它b被实例化为class的对象C。为何以这种方式实施?

Sur*_*tta 5

那么我的输出将是 2。这对我来说是令人惊讶的,因为 b 被实例化为类 C 的对象。为什么它是这样实现的?

静态方法绑定到Type而不是instance。因此,在静态方法的情况下,右侧部分无关紧要。

总之,静态成员属于 class 而不是 instance

请参阅 JLS:15.12.4。方法调用的运行时评估