1 class X {
2 Y b = new Y();
3 X() {
4 System.out.print("X");
5 }
6 }
7
8 class Y {
9 Y() {
10 System.out.print("Y");
11 }
12 }
13
14 public class Z extends X {
15 Y y = new Y();
16 Z() {
17 System.out.print("Z");
18 }
19
20 public static void main(String[] args) {
21 new Z();
22 }
23 }
类在调用构造函数之前,首先要执行初始化类成员的语句,如果继承了其它的类,则先调用父类的构造函数,之后才执行本类的类成员初始化语句,所以执行顺序为(按照行号标识): 21,16,3,2,9,10(Y),3,4,(X), 16,15,9,10(Y),16,17(Z),之后继续执行到结束.()中为该行输出的字符,所以输出结果为YXYZ。
class HelloA
{
public HelloA() {
System.out.println("HelloA");
}
{ System.out.println("I'm A class"); }
static { System.out.println("static A"); }
}
public class HelloB extends HelloA
{
public HelloB() {
System.out.println("HelloB");
}
{ System.out.println("I'm B class"); }
static { System.out.println("static B"); }
public static void main(String[] args) {
new HelloB();
}
}
只以HelloA类为例说明初始化过程:1. static 修饰的静态语句,2.普通类成员的初始化语句,3.构造函数。由于HelloB继承了HelloA,所以只有把HelloA载入内存之后,才会把HelloB载入内存。类中的static块在类被载入内存时立即执行,所以先输出static B,再输出static A。静态块执行完成后,跳转到类的构造函数处,但并不执行其中的构造语句,如果有父类又会跳到父类的构造函数处,但也不立即执行其中的语句。在执行完父类类成员的初始化语句后,才回到父类的构造函数处继续执行,父类构造函数完成后回到子类构造函数,执行子类类成员的初始化,子类属性完成后才回到子类的构造函数处继续执行。
附: jdb命令是jdk附带的一个类似linux gdb的一个调试命令,可以在命令行跟踪程序的运行,详情需参阅文档。