澄清类初始化

时间:2014-11-03 06:37:43

标签: java classloader

类初始化规则声明: 如果由于访问静态字段而触发了类初始化,则只有已声明静态字段的Class才会被初始化,并且它不会触发超类或子类的初始化,即使静态字段由子类,子接口类型或通过接口的实现类。 然后在下面的代码中,只应打印“Initializing Superclass”。

Superclass.java :

public class Superclass {

    public static long INIT_TIME = System.currentTimeMillis();

    static {
        System.out.println("Initializing Superclass");
    }
}

Subclass.java:

public class Subclass extends Superclass {

    static {
        System.out.println("Initializing Subclass");
    }
}

public static void main(String[] args) {

    long time = Subclass.INIT_TIME;         
}   

}

当我运行它时,输出:

Initializing Superclass
Initializing Subclass

3 个答案:

答案 0 :(得分:2)

请参阅第12.1.3章中的Java Language Specification

规则是: “如果Class Test有另一个类Super作为它的超类,那么Super必须在Test之前初始化。”

子类未初始化,但超类是。

答案 1 :(得分:0)

您的代码很可能是这样的:

public class Temp extends SuperTemp {  // subclass

    static {
        System.out.println("Initializing Temp");
    }

}

class SuperTemp {        // super class
    static int i = 0;
    static {
        System.out.println("Initializing SuperTemp");
    }

}

class SomeOtherClass {  

    public static void main(String[] args) {

        System.out.println(Temp.i); // from some other class you are calling SubClass.superClassField
    }
}

O / P:

Initializing SuperTemp
0

原因:在运行期间{J}将Temp.i解析为SuperTemp.i。因此,Temp加载,但已初始化。查看类的加载方式:

java -verbose:class

的O / P.
[Loaded SomeOtherClass from file XXXX]
[Loaded SuperTemp from file XXXX]
[Loaded Temp from file XXXX]
Initializing SuperTemp
0

答案 2 :(得分:0)

正如你所说: -

  
    

如果由于访问静态字段而触发了类初始化,则只有已声明静态字段的Class被初始化并且它不会触发超类或子类的初始化,即使静态字段由子类类型Sub引用也是如此接口或接口的实现类

  

这清楚地表明输出应仅为Initializing Superclass

我运行你的程序并将输出作为

  

初始化超类

     

1414998665110

如果您按照提到的那样获得输出,那么您在问题中没有说明其他内容。

注意: - 参考Jon Skeet就此question提供的答案,似乎该文章的一部分错误地说: -

  

如果由于访问静态字段而触发了类初始化,则只会初始化已声明静态字段的Class,并且不会触发超类的初始化

这与您的情况无关,因为INIT_TIMESuperclass的一部分,因此当您说SuperClass_object.INIT_TIME时,您基本上是在撰写subclass.INIT_TIME。如果您的INIT_TIME而不是Subclass中有Superclass字段,则会输出: -

  

初始化超类

     

初始化子类

     

1414998665110

总结这意味着Superclass gets intialized even if Class initialization is triggered due to access of static field, But Subclass is not initialized.