直接上demo
public class testOne extends TestTwo{
public testOne(){
System.out.println("子类构造方法");
}
{
System.out.println("子类代码块");
}
static {
System.out.println("子类静态代码块");
}
public static void main(String[] args) {
new testOne();
}
}
class TestTwo{
public TestTwo(){
System.out.println("父类构造方法");
}
{
System.out.println("父类代码块");
}
static {
System.out.println("父类静态代码块");
}
public static void find(){
System.out.println("静态方法");
}
}
可以看出到实际上执行顺序应该是
父类静态代码块——>子类静态代码块——>父类代码块——>父类构造方法——>子类代码块——>子类构造方法
但是为什么会这样呢?其实当我们在创建子类时,实际上子类的构造方法的第一行存在一个隐式的super
,super
是一个指向父类的指针,所以在执行构造方法时会通过super来指向父类同时会执行父类的构造方法
。
我们都知道静态代码块是最优先执行的,且只会执行一次
,当子类的super在调用父类的构造方法时所以先回去执行父类的静态代码块,然后执行子类的静态代码块
Java
类初始化顺序
对于静态变量、静态初始化块、变量、初始化块、构造器,它们的初始化顺序依次是(静态变量、静态初始化块)>(变量、初始化块)>构造器。
public class InitialOrderTest {
/* 静态变量 */
public static String staticField = "静态变量";
/* 变量 */
public String field = "变量";
/* 静态初始化块 */
static {
System.out.println( staticField );
System.out.println( "静态初始化块" );
}
/* 初始化块 */
{
System.out.println( field );
System.out.println( "初始化块" );
}
/* 构造器 */
public InitialOrderTest()
{
System.out.println( "构造器" );
}
public static void main( String[] args )
{
new InitialOrderTest();
}
}
运行以上代码,我们会得到如下的输出结果:
- 静态变量
- 静态初始化块
- 变量
- 初始化块
- 构造器
继承父类的时候
class Parent {
/* 静态变量 */
public static String p_StaticField = "父类--静态变量";
/* 变量 */
public String p_Field = "父类--变量";
protected int i = 9;
protected int j = 0;
/* 静态初始化块 */
static {
System.out.println( p_StaticField );
System.out.println( "父类--静态初始化块" );
}
/* 初始化块 */
{
System.out.println( p_Field );
System.out.println( "父类--初始化块" );
}
/* 构造器 */
public Parent()
{
System.out.println( "父类--构造器" );
System.out.println( "i=" + i + ", j=" + j );
j = 20;
}
}
public class SubClass extends Parent {
/* 静态变量 */
public static String s_StaticField = "子类--静态变量";
/* 变量 */
public String s_Field = "子类--变量";
/* 静态初始化块 */
static {
System.out.println( s_StaticField );
System.out.println( "子类--静态初始化块" );
}
/* 初始化块 */
{
System.out.println( s_Field );
System.out.println( "子类--初始化块" );
}
/* 构造器 */
public SubClass()
{
System.out.println( "子类--构造器" );
System.out.println( "i=" + i + ",j=" + j );
}
/* 程序入口 */
public static void main( String[] args )
{
System.out.println( "子类main方法" );
new SubClass();
}
}
输出
- 父类–静态变量
- 父类–静态初始化块
- 子类–静态变量
- 子类–静态初始化块
- 子类main方法
- 父类–变量
- 父类–初始化块
- 父类–构造器
- i=9, j=0
- 子类–变量
- 子类–初始化块
- 子类–构造器
- i=9,j=20
子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。静态变量、静态初始化块,变量、初始化块初始化了顺序取决于它们在类中出现的先后顺序。