Java 静态块、构造块、构造函数执行顺序

2018年07月04日

Java代码行执行顺序:

1.静态块:用static声明,JVM加载类时执行,仅执行一次
2.构造块:类中直接用{}定义,每次创建对象时执行
3.执行顺序优先级:静态块>main()>构造块>构造方法
4.静态块和静态属性优先执行,谁在前先执行谁。

出现继承时:

1.初始化父类的静态变量、静态代码块,初始化的顺序按照出现的顺序。
2.初始化子类的静态变量,静态代码块。
3.初始化父类的成员变量。
4.执行父类的构造函数。
5.初始化子类的成员变量。
6.构造代码块创建对象时执行。
7.执行子类的构造函数。

代码测试及验证:

////Father.java
package com.test;

public class Father {
    protected int n = 5;
    protected static int m = 5;
    public static Father p = new Father();
    public static Father p1 = new Father();

    {//构造块
        n = n * 2;
        m = m * 2;
        System.out.print("父类**构造块**调用;");
        System.out.print("n="+n);
        System.out.println("  m="+m);
    }

    static {//实例化多个对象时,静态块只执行一次,即在第一个实例化对象时执行
        m = m * 2;
        System.out.println("父类%%静态块%%调用; m="+m);
    }


    public Father() {  //父类构造函数
        this.n = n * 10;
        m = m + 10;
        System.out.print("父类$$构造函数$$;   n="+n);
        System.out.println("    m="+m);
    }
}

//Son.java
package com.test;

public class Son extends Father {
    private int sn=3;
    private static int sm=3;
    static {
        m = m + 2;
        sm=sm+2;
        System.out.println("【 子类 】@@ 静态块 @@调用;    m="+m);
    }
    {
        n = n + 2;
        sn=sn+2;
        m = m + 2;
        System.out.println("【 子类 】^^ 构造块 ^^调用;");
        System.out.println("n="+n);
        System.out.println("sn="+sn);
        System.out.println("m="+m);
    }

    public Son() {
        this.n = n + 10;
        sn=sn+10;
        m = m + 10;
        System.out.println("【 子 类 】[[ 构造函数 ]];\nn="+n);
        System.out.println("m="+m);
    }
}

//Main.java
import com.test.Father;
import com.test.Son;

public class Main {

    public static void main(String[] args)
    {


                new com.test.Father();
                new Son();


        System.out.println("Hello World!");
    }
}

运行结果:

    父类**构造块**调用;n=10  m=10
    父类$$构造函数$$n=100    m=20
    父类**构造块**调用;n=10  m=40
    父类$$构造函数$$n=100    m=50
    父类%%静态块%%调用; m=100
    父类**构造块**调用;n=10  m=200
    父类$$构造函数$$n=100    m=210
    【 子类 】@@ 静态块 @@调用;    m=212
    父类**构造块**调用;n=10  m=424
    父类$$构造函数$$n=100    m=434
    【 子类 】^^ 构造块 ^^调用;
    n=102
    sn=5
    m=436
    【 子 类 】[[ 构造函数 ]]n=112
    m=446
    Hello World!
 

如果做如下调整:
结果(二):【将main()函数的new Son()注释掉的运行结果】

**父类**构造块**调用;n=10  m=10
父类$$构造函数$$;   n=100    m=20
父类**构造块**调用;n=10  m=40
父类$$构造函数$$;   n=100    m=50
父类%%静态块%%调用; m=100
父类**构造块**调用;n=10  m=200
父类$$构造函数$$;   n=100    m=210**

结果(三):【将Father类中的两个引用p、p1注释掉的运行结果,结果二中的new Son();也注释掉】

父类%%静态块%%调用; m=10
父类**构造块**调用;n=10  m=20
父类$$构造函数$$;   n=100    m=30

结果(四):【将Father类中的两个引用p、p1注释掉的运行结果,结果二中的new Son();不注释掉】

父类%%静态块%%调用; m=10
父类**构造块**调用;n=10  m=20
父类$$构造函数$$;   n=100    m=30
【 子类 】@@ 静态块 @@调用;    m=32
父类**构造块**调用;n=10  m=64
父类$$构造函数$$;   n=100    m=74
【 子类 】^^ 构造块 ^^调用;
n=102
sn=5
m=76
【 子 类 】[[ 构造函数 ]];
n=112
m=86   ### 输出结果解析:  

期待您的分享与讨论: