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

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   ### 输出结果解析:  

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏用户3030674的专栏

java抽象类和抽象方法之间的关系

抽象类和抽象方法之间的关系 有抽象方法的类,一定是抽象类;抽象类不一定有抽象方法 当子类继承抽象类时,必须要将抽象类中的抽象方法全部实现(或者称为重写),否则子...

14210
来自专栏Jed的技术阶梯

详解 Java 对象与内存控制(上)

不管是类变量还是实例变量,你都不能引用一个还没有定义的变量,或者在引用之前没有定义的变量,如下图所示:

12230
来自专栏编程理解

排序算法(一):冒泡排序

冒泡排序是一种通过交换元素位置实现的稳定排序方式,其特点是每一轮排序后,都会在首端或尾端产生一个已排序元素,就像水泡不断上浮一样,通过多次排序,最终所有元素变得...

14330
来自专栏技术碎碎念

python3 入门 (四) 类与继承

Python 类 Python中的类提供了面向对象编程的所有基本功能:类的继承机制允许多个基类,派生类可以覆盖基类中的任何方法,方法中可以调用基类中的同名方法。...

427120
来自专栏mathor

1小时掌握c++面向对象编程

使用对象指针实参仅将对象的地址值传递给形参,而不进行副本的拷贝,这样可以提高运行效率,减少时间开销

8510
来自专栏LhWorld哥陪你聊算法

【Scala篇】--Scala中的函数

Scala中的函数还是比较重要的,所以本文章把Scala中可能用到的函数列举如下,并做详细说明。

27110
来自专栏Jed的技术阶梯

详解 final 修饰符

被 final 修饰的实例变量必须显示的指定初始值,而且只能在以下3个位置指定初始值:

16840
来自专栏Java帮帮-微信公众号-技术文章全总结

07.Java变量类型

07.Java变量类型 Java 变量类型 在Java语言中,所有的变量在使用前必须声明。声明变量的基本格式如下: ? 格式说明:type为Java数据类型。i...

41270
来自专栏WindCoder

在数组中查找次大值,并与最后一个元素交换—C语言

23810
来自专栏coding for love

JS入门难点解析11-构造函数,原型对象,实例对象

(注1:如果有问题欢迎留言探讨,一起学习!转载请注明出处,喜欢可以点个赞哦!) (注2:更多内容请查看我的目录。)

15910

扫码关注云+社区

领取腾讯云代金券