Java&&(面试题)初始化顺序总结
1 无继承情况下的Java初始化顺序:
![](//img-blog.csdn.net/20141119110433359?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3BfcHJvZ3JhbW1lcg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
class Sample
{
Sample(String s)
{
System.out.println(s);
}
Sample()
{
System.out.println("Sample默认构造函数被调用");
}
}
class Test{
static Sample sam=new Sample("静态成员sam初始化");
Sample sam1=new Sample("sam1成员初始化");
static{
System.out.println("static块运行");
if(sam==null)System.out.println("sam
is null");
sam=new Sample("静态块内初始化sam成员变量");
}
Test()
{
System.out.println("Test默认构造函数被调用");
}
}
//主函数
public static void
main(String str[])
{
Test a=new Test();
}
输出结果为:
静态成员sam初始化 -----静态成员初始化
static块运行 -----静态块被运行
静态块内初始化sam成员变量 ----静态块运行
sam1成员初始化 -----普通成员初始化
Test默认构造函数被调用 -----构造函数运行
由此能够得出结论:
a 静态成员变量首先初始化(注意。Static能够看做一个静态成员。其运行顺序和其在类中申明的顺序有关)
b 普通成员初始化
c 运行构造函数。
对于静态成员(static块能够看成普通的一个静态成员,其并不一定在类初始化时首先运行)和普通成员。其初始化顺序仅仅与其在类定义中的顺序有关,和其它因素无关。
比如以下的样例:
class Test{
static{
System.out.println("static
块 1 运行");
}
static Sample staticSam1=new Sample("静态成员staticSam1初始化");
Sample sam1=new Sample("sam1成员初始化");
static Sample staticSam2=new Sample("静态成员staticSam2初始化");
static{
System.out.println("static
块 2 运行");
}
Test()
{
System.out.println("Test默认构造函数被调用");
}
Sample sam2=new Sample("sam2成员初始化");
}
则结果为:
static 块 1 运行
静态成员staticSam1初始化
静态成员staticSam2初始化
static
块 2 运行
--------静态成员
sam1成员初始化
sam2成员初始化
--------普通成员
Test默认构造函数被调用
--------构造函数
2 Java继承情况下的初始化顺序:
class Test{
static{
System.out.println("父类static
块 1 运行");
}
static Sample staticSam1=new Sample("父类
静态成员staticSam1初始化");
Sample sam1=new Sample("父类
sam1成员初始化");
static Sample staticSam2=new Sample("父类
静态成员staticSam2初始化");
static{
System.out.println("父类
static 块 2 运行");
}
Test()
{
System.out.println("父类
Test默认构造函数被调用");
}
Sample sam2=new Sample("父类
sam2成员初始化");
}
class TestSub extends Test
{
static Sample staticSamSub=new Sample("子类
静态成员staticSamSub初始化");
TestSub()
{
System.out.println("子类
TestSub 默认构造函数被调用");
}
Sample sam1=new Sample("子类
sam1成员初始化");
static Sample staticSamSub1=new Sample("子类
静态成员staticSamSub1初始化");
static{System.out.println("子类
static 块 运行");}
Sample sam2=new Sample("子类
sam2成员初始化");
}
运行结果:
父类 static
块 1 运行
父类 静态成员staticSam1初始化
父类 静态成员staticSam2初始化
父类 static 块 2 运行
--------父类静态成员初始化
子类 静态成员staticSamSub初始化
子类 静态成员staticSamSub1初始化
子类 static 块 运行
-------子类静态成员初始化
父类 sam1成员初始化
父类 sam2成员初始化
父类 Test默认构造函数被调用
-------父类普通成员初始化和构造函数运行
子类 sam1成员初始化
子类 sam2成员初始化
子类 TestSub 默认构造函数被调用
-------子类普通成员初始化和构造函数运行
由此得出Java初始化顺序结论:
1 继承体系的全部静态成员初始化(先父类,后子类)
2 父类初始化完毕(普通成员的初始化-->构造函数的调用)
3 子类初始化(普通成员-->构造函数)
Java初始化顺序如图: