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

发布时间:2023年12月27日

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

运行结果:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

分析:

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

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

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

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

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

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

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

文章来源:https://blog.csdn.net/zhangfuping123456789/article/details/135249780
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。