一、 没有继承情况下:
<span style="font-size:18px;"><strong>package I; import java.awt.image.SampleModel; import java.lang.Thread.State; class Example { static { System.out.println("Example 的静态块"); } { System.out.println("Example 块"); } public Example(String s) { // TODO Auto-generated constructor stub System.out.println(s); } public Example() { // TODO Auto-generated constructor stub System.out.println("默认的构造函数"); } } public class Tset { static Example e = new Example("静态成员的初始化");//先执行Example中的static . 块 Example e_ = new Example(); { System.out.println("块"); } static { System.out.println("Static 块"); if( e== null) System.out.println("e is null"); e = new Example("静态块内部初始化"); } public static void main(String[] args) { // TODO Auto-generated method stub System.out.println("Test 的默认构造函数"); } } </strong></span>
输出的结果是:
<span style="font-size:18px;"><strong>Example 的静态块 Example 块 静态成员的初始化 Static 块 Example 块 静态块内部初始化 Test 的默认构造函数 </strong></span>
由此可以看出,在没有继承关系的提前下:首先执行的是Test类中的静态成员,(静态成员定义的Example类的对象),所以首先输出 Example中的static块中的内容,随后输出Example中块的内容,最后执行的Example的构造器,
第二步执行的是Test中的static块, (Example中的静态块之执行一次),输出Example中的块,之后是构造器。
第三部执行Test中的 成员变量
最后执行main入口中的内容
执行顺序如下:
1、静态成员变量首先初始化 2、普通成员初始化 3、执行构造函数
(static块 可以看成一个静态成员变量,它的执行顺序和它在类中声明的位置有关)
二、Java有继承情况下的初始化顺序:
package I; import java.awt.image.SampleModel; import java.lang.Thread.State; import java.text.SimpleDateFormat; class Sample { Sample(String s) { System.out.println(s); } Sample() { System.out.println("Sample默认构造函数被调用"); } } class Example { static { System.out.println("父类的static 块1"); } static Sample sa = new Sample("父类静态成员1初始化"); Sample saa = new Sample("父类成员1初始化"); static Sample s = new Sample("父类静态成员2初始化"); static { System.out.println("父类的static 块2"); } public Example() { // TODO Auto-generated constructor stub System.out.println("Example默认构造函数的初始化"); } Sample saaa = new Sample("父类成员2初始化"); } public class Tset extends Example{ static Sample s = new Sample("子类静态成员1的初始化"); public Tset() { // TODO Auto-generated constructor stub System.out.println("子类默认构造函数的调用"); } Sample sam1 = new Sample("子类1的初始化"); static Sample s_ = new Sample("子类静态成员2的初始化"); static { System.out.println("子类静态代码块的调用"); } Sample as = new Sample("子类2的初始化"); public static void main(String[] args) { // TODO Auto-generated method stub new Tset(); System.out.println("Test"); } }输出的结果是:
父类的static 块1 父类静态成员1初始化 父类静态成员2初始化 父类的static 块2 子类静态成员1的初始化 子类静态成员2的初始化 子类静态代码块的调用 父类成员1初始化 父类成员2初始化 Example默认构造函数的初始化 子类1的初始化 子类2的初始化 子类默认构造函数的调用 Test第一步执行的是父类静态成员初始化
第二步执行的是子类静态成员初始化
第三步执行的是父类普通成员的初始化和构造函数
第四步执行的是子类普通成员的初始化和构造函数
所以在Java初始化顺序中:
1、 继承体系所有的静态成员初始化(先是父类,后是子类)
2、父类初始化完成(普通成员的初始化->构造器)
3、子类初始化(普通成员的初始化->构造器)