给定以下类:
public abstract class Super {
protected static Object staticVar;
protected static void staticMethod() {
System.out.println( staticVar );
}
}
public class Sub extends Super {
static {
staticVar = new Object();
}
// Declaring a method with the same signature here,
// thus hiding Super.staticMethod(), avoids staticVar being null
/*
public static void staticMethod() {
Super.staticMethod();
}
*/
}
public class UserClass {
public static void main( String[] args ) {
new UserClass().method();
}
void method() {
Sub.staticMethod(); // prints "null"
}
}
我的目标不是像“因为它在 JLS 中是这样指定的。”这样的答案。我知道是的,因为JLS, 12.4.1 When Initialization Occurs只读:
A class or interface type T will be initialized immediately before the first occurrence of any one of the following:
...
T is a class and a static method declared by T is invoked.
...
我感兴趣的是是否有充分的理由为什么没有像这样的句子:
- T is a subclass of S and a static method declared by S is invoked on T.
最佳答案
请注意您的标题,静态字段和方法不是继承的。这意味着当您在 Sub
中注释 staticMethod()
时,Sub.staticMethod()
实际上调用了 Super.staticMethod()
然后 Sub
不执行静态初始值设定项。
然而,这个问题比我第一眼看到的更有趣:在我看来,这不应该在没有警告的情况下编译,就像在类的实例上调用静态方法一样。
编辑: 正如@GeroldBroser 指出的那样,这个答案的第一个陈述是错误的。静态方法也被继承但从不被覆盖,只是被隐藏。我将保留历史的答案。
关于java - 为什么在子类上调用在其父类(super class)中声明的静态方法时不调用子类的静态初始化程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25941744/