Java中静态代码块、代码块以及构造函数执行顺序详解,Java类初始化顺序

直接上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("静态方法");
    }
}

在这里插入图片描述

可以看出到实际上执行顺序应该是
父类静态代码块——>子类静态代码块——>父类代码块——>父类构造方法——>子类代码块——>子类构造方法
但是为什么会这样呢?其实当我们在创建子类时,实际上子类的构造方法的第一行存在一个隐式的supersuper是一个指向父类的指针,所以在执行构造方法时会通过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();
    }
}

运行以上代码,我们会得到如下的输出结果:

  1. 静态变量
  2. 静态初始化块
  3. 变量
  4. 初始化块
  5. 构造器

继承父类的时候

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();
    }
}

输出

  1. 父类–静态变量
  2. 父类–静态初始化块
  3. 子类–静态变量
  4. 子类–静态初始化块
  5. 子类main方法
  6. 父类–变量
  7. 父类–初始化块
  8. 父类–构造器
  9. i=9, j=0
  10. 子类–变量
  11. 子类–初始化块
  12. 子类–构造器
  13. i=9,j=20

子类的静态变量和静态初始化块的初始化是在父类的变量、初始化块和构造器初始化之前就完成了。静态变量、静态初始化块,变量、初始化块初始化了顺序取决于它们在类中出现的先后顺序。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值