为什么静态块不会在被调用对象中加载?

时间:2014-03-05 07:59:57

标签: java

class Super { static String ID = "SUPER_ID"; }

class SubClass extends Super{
  static { System.out.print("In SubClass"); }
}

class Test{
  public static void main(String[] args) {
    System.out.println(SubClass.ID);
  }
}

为什么我有输出

SUPER_ID

而不是

In SubClass
SUPER_ID


SubClass 将在第一次调用object时加载。那么为什么static init块不执行? 感谢。

3 个答案:

答案 0 :(得分:1)

因为在编译时本身,SubClass.ID将由编译器更改为Super.ID。 就像@Kugathasan Abimaran所说,继承和静态是两回事。

示例:

public class SampleClass {
    public static void main(String[] args) {
        System.out.println(SubClass.ID);
        System.out.println(SubClass.i);
    }
}

class Super {
    static String ID = "SUPER_ID";
}

class SubClass extends Super {
    static {
        System.out.println("In SubClass");
    }

    static int i;
}

Output :
SUPER_ID
In SubClass // only when accessing a variable of subclass, the class will be initialized.
0

答案 1 :(得分:0)

您的类未被类加载器加载,因为它未在测试类中使用,如果您要加载它,只需在测试类中添加语句Class.forName("SubClass");,之后能够像你期待的那样看到结果。您也可以使用类加载器而不是Class.forName加载此类。

class Test{
    public static void main(String[] args) {
    Class.forName("SubClass");
    //Thread.currentThread().getContextClassLoader().loadClass("SubClass");
    System.out.println(SubClass.ID);
    }
}

答案 2 :(得分:0)

根据Java语言规范:

  

对静态字段的引用仅导致类或类的初始化   实际声明它的接口,即使它可能通过引用   子类的名称,子接口或实现接口的类。

More info