我正在阅读关于静态方法的阴影,我无法理解一件事,编译器如何选择运行方法。 假设我有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;
}
}
显然,当我调用方法A.test()
B.test()
C.test()
时,我会得到结果1
2
3
但是如果我从实例中调用它(我知道不好的做法),那么当这段代码:
时C c = new C();
System.out.println(c.test());
将按照我的预期打印3,但是当我这样做时
B b = c;
System.out.println(b.test());
然后我的输出将是2。
这对我来说是令人惊讶的,因为b
被实例化为类C
的对象。有没有理由这样实现呢?
答案 0 :(得分:3)
然后我的输出将是2.这对我来说是令人惊讶的,因为b实例化为C类的对象。为什么它被实现的原因是什么?
静态方法绑定到类型而不是实例。因此,在静态方法的情况下,右侧部分并不重要。
Inshort,静态成员属于类而不是实例。
答案 1 :(得分:2)
决策由编译器决定,并且基于声明的变量类型。对象的运行时类型 - 这对于例如方法来说很重要 - 根本没有被考虑过。实际上,您可以通过一个设置为null的引用变量调用静态方法,它可以正常工作。
答案 2 :(得分:2)
首先通过实例访问静态方法是不好的&编译器应该给你一个警告。你应该留意它。然后,当您调用b.test
时,b
的类型是B而不是C,正如您所期望的那样。所以调用了B.test
。
答案 3 :(得分:0)
如果子类定义的静态方法与超类中的静态方法具有相同的签名,则子类中的方法会隐藏超类中的方法。
如果你有静态方法而不是重要的参考类型而不是参考引用的实际对象。
根据引用类型而不是实际对象调用静态方法。
Super s=new Sub();
这里如果你在s上调用静态方法,检查引用类型是否为Super 所以称为超类方法。
请参阅this