我正在阅读有关静态方法的阴影,但我不明白一件事,即编译器如何选择要运行的方法。假设我有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
。为何以这种方式实施?
那么我的输出将是 2。这对我来说是令人惊讶的,因为 b 被实例化为类 C 的对象。为什么它是这样实现的?
静态方法绑定到Type而不是instance。因此,在静态方法的情况下,右侧部分无关紧要。
总之,静态成员属于 class 而不是 instance。
请参阅 JLS:15.12.4。方法调用的运行时评估