如何在java中初始化类层次结构的类?

时间:2015-06-16 15:51:11

标签: java inheritance

调试子表达式

Sub.x

表达式中的

System.out.println(Sub.x);

在下面给出的代码中,了解类的运行时类的初始化规则,即JVM内存空间中的。{,{1}}和class Sub

class Super

调试之后,观察是package defaultvalues; import java.util.*; class Super{ static int x; static{ System.out.println("Super"); } } class Sub extends Super{ Date date; {//instance initialisation block for date Calendar temp = Calendar.getInstance(); date = temp.getTime(); } static{ System.out.println("Sub"); } long alarm; } class Game{ static Random rand; static{ rand = new Random(); } static void tossCoin(){ if(rand.nextBoolean()){ System.out.println("Heads"); }else{ System.out.println("Tails"); } } } public class Example { public static void main(String[] args) { System.out.println(Sub.x); // class Super is loaded. From class Super, static members are //initialised and static initialisation blocks are executed before executing expression 'Sub.x' Game.tossCoin(); // class Game is loaded. From class Game, static members are initialised //and static initialiser blocks are executed before executing expression 'Game.tossCoin()' Sub obj = new Sub(); //instance variables are initialised and instance initialisation block //of class A are executed. System.out.println(obj.date); System.out.println(obj.alarm); } } 被初始化,但class Super在表达式class Sub被评估之前没有被初始化。评估表达式Sub.x后的立即输出是:

System.out.println(Sub.x);

因此,Super 0 在表达式System.out.println("Sub");被评估之前不会执行。

关于此表达式Sub.x评估,在源代码中,我看到表达式Sub.x正在评估,Sub.x已初始化但未class Super

我的问题是:

class Sub是否已加载&在运行期间评估子表达式class Sub之前已链接但未初始化?

注意:在Eclipse环境中工作

2 个答案:

答案 0 :(得分:3)

您描述的行为在JLS的示例中给出,here

  

例12.4.1-2。只有声明静态字段的类   初始化

class Super {
    static int taxi = 1729;
}
class Sub extends Super {
    static { System.out.print("Sub "); }
}
class Test {
    public static void main(String[] args) {
        System.out.println(Sub.taxi);
    }
}
     

此程序仅打印:

1729
     

因为类Sub从未初始化;对Sub.taxi的引用   是对类Super中实际声明的字段的引用   不会触发类Sub的初始化。

匹配初始化列表的原因

  
      
  • 使用T声明的静态字段,该字段不是常量变量(§4.12.4)。
  •   

该字段由Super声明,而不是Sub

答案 1 :(得分:2)

这是因为你还没有触发static class initialization

在回答相关问题here时,答案讨论了触发类初始化的各种方法。

如果你在类getX()中创建了一个方法Sub,它从它的超类返回x,它应该为Sub执行静态类初始化。

JLS-12.4.1中的更多内容。

在这种情况下请注意“分配了由T声明的静态字段”。似乎不适用,因为x是在超类中声明的。