0
点赞
收藏
分享

微信扫一扫

父子类在创建对象时的加载顺序

看山远兮 2022-03-23 阅读 106
java

子继承父,在创建对象时,对资源加载的过程的理解

说明:

1. 一个new Leaf();

package com.zy.controller;

/**
 * 先父后子,静态先行
 */
public class Root {
    String name;
    Integer age;

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

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

    public Root() {
        System.out.println("Root的空参构造器");
    }

    public Root(String name, Integer age) {
        this();
        System.out.println("Root的非空参构造器");
        this.name = name;
        this.age = age;
    }
}

class Mid extends Root {



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

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

    public Mid() {
        System.out.println("Mid的空参构造器");
    }

    public Mid(String name, Integer age) {
        this();
        System.out.println("Mid的非空参构造器");
        this.name = name;
        this.age = age;
    }


}

class Leaf extends Mid {


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

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


    public Leaf() {
        super("名字",18);
        System.out.println("Leaf的空参构造器");
    }
}



 class ExtendsTest {
    public static void main(String[] args) {
        new Leaf();

    }
}


控制台输出:
    
Root的静态代码块
Mid的静态代码块
Leaf的静态代码块
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器

解析:

new Leaf();时,Leaf有父类Mid类,所以先加载Mid类,但是mid类也有父类Root类,所以加载root类,Root类有Object类,所以先加载Object类,再加载root类,再加载mid,之后是leaf。

顺序是 Object类 -> Root类 -> Mid类 -> Leaf类

加载类时的加载顺序:静态资源 -> 非静态代码块 -> 构造器。

所以运行顺序是

Root静态代码块 -> Mid静态代码块 ->Leaf静态代码块 -> Root非静态代码块 -> Root构造器 -> Mid非静态代码块 -> Mid空参构造器 -> Mid非空参构造器 -> Leaf的非静态代码块 -> Leaf的空参构造器

2. 两个new Leaf();

package com.zy.controller;

/**
 * 先父后子,静态先行
 */
public class Root {
    String name;
    Integer age;

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

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

    public Root() {
        System.out.println("Root的空参构造器");
    }

    public Root(String name, Integer age) {
        this();
        System.out.println("Root的非空参构造器");
        this.name = name;
        this.age = age;
    }
}

class Mid extends Root {



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

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

    public Mid() {
        System.out.println("Mid的空参构造器");
    }

    public Mid(String name, Integer age) {
        this();
        System.out.println("Mid的非空参构造器");
        this.name = name;
        this.age = age;
    }


}

class Leaf extends Mid {


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

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


    public Leaf() {
        super("名字",18);
        System.out.println("Leaf的空参构造器");
    }
}



 class ExtendsTest {
    public static void main(String[] args) {
        new Leaf();
        System.out.println("---------------------------");
        new Leaf();
    }
}


控制台输出:

Root的静态代码块
Mid的静态代码块
Leaf的静态代码块
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器
---------------------------
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器

Process finished with exit code 0

解析:

第一次 new Leaf();已经加载过静态代码块,第二次 new Leaf();不需要再加载静态代码块,两个new的对象共用一个常量池里面的静态资源。其他的和第一个new Leaf();一样

举报

相关推荐

0 条评论