一、 没有继承情况下:
<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、子类初始化(普通成员的初始化->构造器)