Java父类子类加载顺序

父类如下:

package zzm.java.extendsDemo;

public class Parent {
    /**
     * 会报错,因为static按顺序进行加载的
     */
//    static {
//        System.out.println("i="+i);
//    }

    public static int i = 0;

    {
        i++;
        System.out.println("i(非静态)="+i);
    }

    static {
        i = i+1;
        System.out.println("i(静态)="+i);
    }

    {
        i++;
        System.out.println("i(非静态)="+i);
    }

    public Parent(){
        i++;
        System.out.println("i(构造方法)="+i);
    }

}

子类如下:

package zzm.java.extendsDemo;

public class Child extends Parent{
    public static int i = 0;

    {
        i++;
        System.out.println("i(子类非静态)="+i);
    }

    static {
        i = i+1;
        System.out.println("i(子类静态)="+i);
    }

    {
        i++;
        System.out.println("i(子类非静态)="+i);
    }

    public Child(){
        //显示调用父类构造方法,必须放在最前面,和不写是一样的
        super();
        i++;
        System.out.println("i(子类构造方法)="+i);
    }

    public static void main(String[] args) {
       Child child1 =  new Child();
       Child child2 = new Child();
    }
}

猜猜输出是啥?

下面是打印

i(静态)=1
i(子类静态)=1
i(非静态)=2
i(非静态)=3
i(构造方法)=4
i(子类非静态)=2
i(子类非静态)=3
i(子类构造方法)=4
i(非静态)=5
i(非静态)=6
i(构造方法)=7
i(子类非静态)=5
i(子类非静态)=6
i(子类构造方法)=7

由此我们得出下面几个结论:

1、先执行父类的静态变量、静态方法块,谁在前面谁先执行

2、在执行子类的静态变量、静态方法块,也是一样,谁在前面谁先执行

3、在执行父类的非静态变量、非静态方法块,接着执行对应子类

4、最后在执行父类构造方法、在执行子类构造方法

5、当类已经被加载后,第二次加载时不会在执行静态变量的赋值,已经静态方法块,但是会执行非静态变量的赋值和非静态方法块。

因为一个静态变量的初始化是在类加载的准备阶段,这个阶段会执行静态变量的赋值以及相关的静态代码块,是<client>()方法执行的,执行时机是类加载的时候

而非静态方法,是由<init>()方法执行的,执行时间是构造实例的时候,随着实例化时一起放在堆上

posted @ 2022-08-01 00:25  一花一世界!  阅读(1025)  评论(1编辑  收藏  举报