[java code]
class Java_StaticVariableTest{
private static int six;
static {
System.out.println("six="+six);
}
private static Java_StaticVariableTest one=new Java_StaticVariableTest();
private int five=0;
private static int four=0;
static {
System.out.println("six="+six);
one.print();
}
private static int two;
private static int three=0;
Java_StaticVariableTest(){
System.out.println("five="+five);
two++;
three++;
four++;
five++;
six++;
System.out.println("one="+one);
}
void print(){
System.out.println("two="+two+" three="+three+" four="+four+" five="+five);
}
public static void main(String[] args){
one.print();
}
}
[/Java code]
/*
打印结果:
six=0
five=0
one=null 
six=1
two=1 three=1 four=0 five=1
two=1 three=0 four=0 five=1
总结:
由one=null可以得知在创建Java_StaticVariableTest对象时,one变量已经声明了。
由two和three的二次输出结果可以得出,static域是先自动初始化变量后再进行赋值。
再从four和six的二次输出结果可以得出,static域是先执行变量初始化后按照(赋值和静态块同优先级)从上到下的顺序执行。
在由7/8行位置和five的三次输出结果可以得出,程序在执行第7行的创建对象前已经把five给声明好并初始化。
*/
求大神解释上面static的问题。。为什么会出现这情况。jvm是怎么做的,越详细越好谢谢!!!
csdn什么时候更新到想插入代码都找不到哪个插入按钮

解决方案 »

  1.   

    其实这个问题和jvm关系不大,关键是编译器处理的问题。
    再就是“由one=null可以得知在创建Java_StaticVariableTest对象时,one变量已经声明了。”其实,类型定义中有哪些static变量,哪些instance变量在运行的时候已经是确定的了,不存在“声明”一说。所以,也要注意区分编译和运行两个不同的时期。楼主提供的代码,javac处理完毕之后会把所有的static {}和static变量的初始化语句按出现的顺序整理到一起,可以认为编译器处理之后static初始化是这样的: static {
    System.out.println("six=" + six); one = new Java_StaticVariableTest(); four = 0; System.out.println("six=" + six);
    one.print(); three = 0;
    }
    jvm加载类,给static变量分配空间之后会执行默认初始化,比如整数初始化为0等等。
    然后调用用户定义的static初始化信息。
      

  2.   


    加载的时候,其实就已经做了默认的初始化了,在执行的时候再做用户定义的,是这样?但是里面那个instance变量又是怎么做的?记得java的成员变量都是有默认初始化的几个时期都还不是很了解
      

  3.   

    实例变量是创建对象的时候初始化,new分配内存,然后将所有实例变量初始化为0(大概,跟具体类型有关,你所谓的默认初始化),然后调用构造器执行用户定义的初始化。用户定义的实例变量初始化语句同样被编译器提取出来,放在构造器其他语句之前。比如你的代码中,five=0;可以认为被处理成了这个样子:
    Java_StaticVariableTest() {
    five = 0;

    System.out.println("five=" + five);
    two++;
    three++;
    four++;
    five++;
    six++;
    System.out.println("one=" + one);
    }