调试子表达式
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环境中工作
答案 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
是在超类中声明的。