| public class InitializationTest { public static void main(String args[]) { Child c; System.out.println("program start"); System.out.println(Child.scm1); c= new Child(10); System.out.println("program end"); } } |
进入此文件所在的目录,然后 编译此文件:javac InitializationTest.java 运行此程序:java ?classpath . InitializationTest 得到的结果是:
| program start Parent's static initialize block Child's static initialize block 10 Parent's method Parent's instance initialize block Parent's default constructor Child's method Child's instance initialize block Other's default constructor Child's default constructor Child's self-define constructor program end |
如果没有看过上面的关于类的构造的说明,很容易让人误解为类的构造顺序是如下的结果(忽略参数绑定、内存分配和非静态成员的缺省值赋值): 1.完成父类的非静态成员初始化赋值以及执行初始化块(这个的先后顺序取决于源文件中的书写顺序,可以将初始化块置于成员声明前,那么先执行的将是初始化块,将上面的代码稍稍变动一下就可以验证这一点。) 2.调用父类的构造方法完成父类构造。 3.完成非静态成员的初始化赋值以及执行初始化块。 4.调用构造方法完成对象的构造,执行构造方法体中的其它内容。 如果根据以上java规范中给出的顺序也可以合理的解释程序的输出结果,那么如何亲眼看到是规范中的顺序而不是以上根据程序的输出推断的顺序呢? 下面就使用JDK自带的javap工具看看实际的顺序,这个工具是一个根据编译后的字节码生成一份字节码的助记符格式的文档的工具,就像根据机器码生成汇编代码那样。
|