Java代码的执行顺序,静态代码块、静态成员变量的执行顺序,有父子类的继承时的执行顺序(代码图文演示)

本文详细解释了Java代码中静态代码块、静态成员变量、非静态代码块及构造方法的执行顺序,包括没有父子类和有父子类情况下的执行逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java代码的执行顺序

也就是一个类中有很多部分的代码,它们的执行顺序是怎样的?

一、没有父子级时的执行顺序

1、 静态代码块 和 main 方法:先执行 静态代码块,与位置无关

2、 假如类中定义 静态成员变量(该变量是个对象,普通的成员变量也适用),那么会先创建对象:

假如 2 的代码块在 1 的前面写,则先执行 2,是由位置决定的。而 main 始终在 1,2 最后,跟位置没有关系。

3、 需注意:

① 如果是非静态代码块、非静态成员变量(该变量是个对象),是不会执行的:

② 这个时候,只有在创建 Test 对象的时候(也就是它们所在类的对象),才会执行 非静态代码块、非静态成员变量(该变量是个对象):此时 三者的执行的顺序 是按照位置的先后。

4、 如果同时存在 非静态代码块、静态代码块、非静态成员变量(对象)、静态成员变量(对象):

先执行静态的东西,并且只执行一次;再执行非静态的东西(能执行的前提:先创建对象),创建多少个就执行多少次。

二、有父子级时的执行顺序

有资源类 Res、父类 Parent、子类 Children,测试类 Test。代码分别如下,那执行顺序是怎样的?

public class Res {
    public Res(String str){
        System.out.println(str + "方式:调用 Res 的构造方法,创建 Res 资源。");
    }
}           
public class Parent {

    static Res parentRes = new Res("父类的静态成员变量,该变量(是父类创建 Res 对象)");

    static {
        System.out.println("父类的静态代码块");
    }

    {
        System.out.println("父类的非静态代码块");
    }

    Res parentRes1 = new Res("父类的非静态成员变量,该变量(是父类创建 Res 对象)");

    Res parentRes2;

    public Parent(){
        System.out.println("父类的无参构造");
        parentRes2 = new Res("在父类的无参构造中创建 Res 对象");
    }

    public void sayHello(){
        System.out.println("父类的普通方法");
    }
}
public class Children extends Parent{

    static Res childrenRes = new Res("子类的静态成员变量,该变量(是子类创建 Res 对象)");

    static {
        System.out.println("子类的静态代码块");
    }

    {
        System.out.println("子类的非静态代码块");
    }

    Res childrenRes1 = new Res("父类的非静态成员变量,该变量(是子类创建 Res 对象)");

    Res childrenRes2;

    public Children(){
        System.out.println("子类的无参构造");
        childrenRes2 = new Res("在子类的无参构造中创建 Res 对象");
    }

    public void sayHello(){
        System.out.println("子类的普通方法");
    }
}
public class Test {
    public static void main(String[] args) {
        Children children = new Children();
        children.sayHello();
        System.out.println("*******");
        //子类强转父类后,再调方法
        ((Parent) children).sayHello();
    }
}

运行结果:

父类的静态成员变量,该变量(是父类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
父类的静态代码块
子类的静态成员变量,该变量(是子类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
子类的静态代码块
父类的非静态代码块
父类的非静态成员变量,该变量(是父类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
父类的无参构造
在父类的无参构造中创建 Res 对象,方式:调用 Res 的构造方法,创建Res 对象。
子类的非静态代码块
子类的非静态成员变量,该变量(是子类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
子类的无参构造
在子类的无参构造中创建 Res 对象,方式:调用 Res 的构造方法,创建Res 对象。
子类的普通方法
在这里插入图片描述
子类的普通方法

分析:

① 首先代码从 main 方法入口开始

Children children = new Children(); 创建子类对象、会调子类的构造器,子类构造器的首行默认会有 super() 方法,所以会 优先调父类的无参构造,所以会先加载 Parent 类,其中 静态代码块 和 静态成员变量 会优先执行,即输出前 2 行:

父类的静态成员变量,该变量(是父类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
父类的静态代码块

③ Parent 类加载完后,再去加载 Children 类,因为 先加载类再执行,所以输出第3、4行:

子类的静态成员变量,该变量(是子类创建 Res 对象),方式:调用 Res 的构造方法,创建 Res 对象。
子类的静态代码块

④ 类都加载完后,就开始创建对象,默认会先创建父类对象,但调构造器之前会先执行类中的 非静态东西,然后再开始通过父类自己的无参构造创建父类对象,所以输出第5、6、7、8行:

父类的东西都搞完后,再开始搞子类的东西,同理,输出9、10、11、12行:

创建对象完后,对象开始执行方法children.sayHello();,输出13、14行:

⑦ 虽然进行了强制类型转换,但对象还是来自内存中的子类对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小学鸡!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值