先看代码:
public class Test {
static int a=1;
static {
new InnerStaticClass();
}
static int b=2;
static {
System.out.println("b="+b);
}
static class InnerStaticClass{
InnerStaticClass(){
System.out.println("a="+a);
System.out.println("b="+b);
}
}
public static void main(String[] args) {
new Test();
}
}
得到输出的结果是:
a=1
b=0
b=2
我不明白的是:为什么这里的b会有两个值,一个是0一个是2 ?我写的代码是在初始化时使b=2呀,而在这里使b=0的操作是什么时候执行的呢?我知道在第一个static初始化块中执行“new InnerStaticClass()”语句时b还没有初始化,那这里的b=0是从何而来呢?很显然,输出结果中的b=2我明白,它是在执行第二个static初始化块时输出的,这时b已经被初始化为2了,我就是不明白第一个static初始化块为什么打印出来是b=0?有哪位老师愿意解释一下呢?谢谢您了!
是这样的,jvm在加载类的时候,先只是建立的一堆索引而已,类属性的默认值都为0,然后再赋值,不是说你给个private int a = 1;那么a就等于1了,总得有个先后顺序。先建立类的每个属性索引,然后才会赋值。
这个你可以通过debug模式来看芽,我刚才帮你小看了一下,结果是这样的:
[code="java"]
public class MainDemo {
static int a = 1; //@1
static {
new InnerStaticClass(); //@2
}
static int b = 2;//@5
static {
System.out.println("b=" + b);//@6
}
static class InnerStaticClass {
InnerStaticClass() {
System.out.println("a=" + a); //@3
System.out.println("b=" + b); //@4
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
new MainDemo();//@0
}
}
//运行顺序:@0->@6
@1时 a = 1,b = 0;
@2时输出的上面的值;
然后后面的b=2再输出。
[/code]
这里你需要搞明白的是,即使是对象属性,是先;建立堆后进行赋值
对于 283433775 (资深程序员) 的回答
1、后面的标号是指程序的执行或初始化顺序
2、
@1:static int a = 1; // 此时a=1
@2:
进入InnerStaticClass构造函数
@3:@2之后来到了此处,System.out.println("a=" + a);
此时a已经初始化好,直接打印出来a=1
@4:System.out.println("b=" + b);
此时要打印出b,发现b还没有初始化(注意,b在@5处还没有执行,还没被初始化),故要先要初始化b,由于还没有执行@5,故b值此时为0(Java声明变量会有默认值,整型为0),打印出b=0
@5:static int b = 2; // 此时b被赋值为2
@6:打印出b的值b=2
静态变量和静态代码块是按定义的顺序执行的,在此程序中是由上往下