例一:两个class的执行顺序问题:
class StaticTry
{
int num;
StaticTry(int x)
{
this.num = x;
System.out.println("构造函数被执行----> "+num);
}
static
{
System.out.println("Static静态代码块被执行 ");
}
{
System.out.println("Static构造代码块被执行----> "+num);
}
}
class StaticDemo
{
public static void main(String[] args)
{
StaticTry s = new StaticTry(10);
System.out.println("最后一步!");
}
static
{
System.out.println("StaticDemo静态代码块被执行!");
}
}
输出结果为:
StaticDemo静态代码块被执行!
Static静态代码块被执行
Static构造代码块被执行----> 0
构造函数被执行----> 10
最后一步!
值得注意的是:
Static构造代码块被执行后的数字和构造函数被执行后的数字的不同。
说明:
内存先加载StaticDemo.class,故先执行StaticDemo静态代码块,当读到语句StaticTry s = new StaticTry(10);时,才加载StaticTry.class,此时执行static静态代码块。
例二:一个class中的顺序问题
class Person
{
private int age = 3;
private static String nationality = "China";
private String name;
Person(String name,int age)//构造函数
{
this.name = name;
this.age = age;
System.out.println("构造函数被执行!"+name+" + "+age+" + "+nationality);
}
static //静态代码块
{
System.out.println("静态代码块被执行! "+nationnality);
System.out.println("静态代码块被执行! "+name); //编译错误,此时实例变量name尚未加载进内存
System.out.println("静态代码块被执行! "+age); //编译错误,此时实例变量age尚未加载进内存
}
{ //构造代码块
System.out.println("构造代码块被执行!"+name+" + "+age+" + "+nationality);
}
}
class exeOrderDemo
{
public static void main(String[] args)
{
Person xiaoming = new Person("Xiaoming",20);
}
}
输出:
静态代码块被执行! China
构造代码块被执行!null + 3 + China
构造函数被执行!Xiaoming + 20 + China
说明:
1、看到语句 : Person xiaoming = new Person("Xiaoming",20); 就把Person.class加载到内存中;
2、对person这个类进行显示初始化,这里表现为对nationality赋值"China"
3、对person这个类执行静态代码块,输出在第二步中被赋值的nationality =="China"
4、在堆中开辟空间
5、执行xiaoming这个实例对象的默认初始化,即name=null,age=0
6、执行xiaoming 这个实例对象的显示初始化,即age=3
7、执行xiaoming这个实例对象的构造代码块,输出在第4,5步中赋值的name和age
8、执行xiaoming这个实例对象的构造函数,输出已经赋值了的name,age,和nationality
9、将以上5~8步中在内存中的首地址赋给栈中的引用xiaoming.
试验:
若将构造函数中的s.o.p语句放在this语句之前,且写为:System.out.println("构造函数被执行!"+this.name+" + "+this.age+" + "+nationality);
输出会是什么?