本帖最后由 姚鑫 于 2012-3-1 22:23 编辑
这个问题要结合java内存管理来讲,示例代码如下:
class Person {
private String name;
private int age;
private static String country ;
static {
country = "China";
System.out.println("静态代码块");
}
{
System.out.println("构造代码块");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("构造函数");
}
public String toString() {
return "name:"+ name + " age:" + age + " country:" + country;
}
}
class Test {
public static void main(String[] args) {
Person p = new Person("Lisi",18);
System.out.println(p);
}
}
打印结果是:
静态代码块
构造代码块
构造函数
name:Lisi age:18 country:China
步骤分析:
第一步:当运行java Test命令时,首先JVM会找到Test.class文件,读取这个文件的二进制数据,存放到方法区,叫做类的的加载过程。
第二步:JVM定位到Test类的Main()方法的字节码,在栈中开辟Main函数的空间,开始执行其中的指令。
第三步:遇到Person p = new Person("Lisi",18); 先在栈中Main函数的空间建立p变量,然后JVM看到Person类,就直奔方法区,想找到Person类的字节码,一看没有,就加载吧。
第四步:加载Person的字节码,遇到了static String country ;在方法区中开辟空间存放这个静态变量,并默认初始化,如果有初值,再显示初始化;加载完后执行静态代码块,将country赋值为"China";
第五步:有了Person类的信息,就在堆中开辟空间,实例化对象,建立name和age这两个全局变量,并默认初始化,如果有初值,再显示初始化。
第六步:执行构造代码块。
第七步:构造函数初始化。
第八步:将堆中的这个实例的内存地址赋给栈中的p变量。
根据分析排序是:
静态变量的默认初始化→静态变量显示初始化→静态代码块→对象全局变量默认初始化→对象全局变量显示初始化→构造代码块→构造函数 |