使用子类名访问父类静态字段不会加载子类?

时间:2014-03-22 19:36:16

标签: java inheritance static

class A {
    static int super_var = 1;
    static {
        System.out.println("super");
    }
}

class B extends A {
    static int sub_var = 2;
    static {
        System.out.println("sub");
    }    
}
public class Demo{
    public static void main(String []args){
        System.out.println(B.super_var);
    }
}

输出是:

super
1

这意味着子类不会加载或任何其他东西?它是如何运作的?

2 个答案:

答案 0 :(得分:12)

当您在子类引用上访问超类的static字段时,只会加载和初始化声明该字段的类,在这种情况下它是A。这在JLS §12.4.1 - When Initialization Occurs

中指定
  

static字段(第8.3.1.1节)的引用仅导致初始化   实际声明它的类或接口,即使它可能   通过子类的名称,子接口或a来引用   实现接口的类。

强调我的。

因此,在您的代码中,类B甚至不会被初始化,因此它的static块将不会被执行。

答案 1 :(得分:0)

查看此问题的答案:In what order do static initializer blocks in Java run?

只有在访问类(创建实例或访问成员字段或静态方法)时才会调用静态块。但是,您只能访问A类成员,因此没有理由初始化B类。一旦从该类访问成员(字段或静态方法,或从类B创建实例),就会调用B的静态初始化程序。

原因是在访问其中一个成员之前,不需要初始化B类。因为A不知道B(并且不能访问它),所以B在该阶段没有理由进行初始化。

当您访问 B.sub_var 时,您会发现B的静态初始化程序将被执行。