Java 几种代码块的执行顺序,你知道吗?

  • A+
所属分类:JAVA


共计 1659 个字符,预计需要花费 5 分钟才能阅读完成。

本文源于一道笔试题而来,讲一讲Java中静态代码块、非静态代码块、构造方法的执行顺序及原理:

package cn.peiluming.test1.test1_1;

/**
 * @author plm
 * @create 2021/2/22 21:50
 */
public class DemoA {
    public DemoA() {
        System.out.println("DemoA 构造方法。");
    }

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

    static {
        System.out.println("DemoA 静态代码块。");
    }
}
package cn.peiluming.test1.test1_1;

/**
 * @author plm
 * @create 2021/2/22 21:52
 */
public class DemoB extends DemoA {
    public DemoB() {
        System.out.println("DemoB 构造方法。");
    }

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

    static {
        System.out.println("DemoB 静态代码块。");
    }
}
package cn.peiluming.test1.test1_1;

/**
 * @author plm
 * @create 2021/2/22 21:53
 */
public class DemoC extends DemoB {
    public DemoC() {
        System.out.println("DemoC 构造方法。");
    }

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

    static {
        System.out.println("DemoC 静态代码块。");
    }
}
package cn.peiluming.test1.test1_1;

/**
 * @author plm
 * @create 2021/2/22 21:54
 */
public class DemoTest {
    public static void main(String[] args) {
        // 简单的进行new一个对象
        DemoC c = new DemoC();
    }
}
/* 输出
DemoA 静态代码块。
DemoB 静态代码块。
DemoC 静态代码块。
DemoA 非静态代码块。
DemoA 构造方法。
DemoB 非静态代码块。
DemoB 构造方法。
DemoC 非静态代码块。
DemoC 构造方法。
 */

奉上代码,可简单发现执行顺序:父静态代码块 -> 子静态代码块 -> 父非静态代码块 -> 父构造方法 -> 子非静态代码块 -> 子构造方法

首先DemoC实例化时,需要调用其构造方法,那我们都知道,子类的构造方法体默认会首先执行super(),先加载父类;
我们之前也了解过,static修饰的都会在类加载时先执行,所以按照类加载顺序,先执行(初始化)静态域;

指针又回到父类DemoA这儿了,为什么是先执行非静态代码块,在执行构造方法,这里有个小迷惑,我拿出DemoA的字节码文件DemoA.class,瞧一瞧:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package cn.peiluming.test1.test1_1;

public class DemoA {
    public DemoA() {
        System.out.println("DemoA 非静态代码块。");
        System.out.println("DemoA 构造方法。");
    }

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

哎呀😕,不对劲,这个非静态代码块被放到构造方法体中去了,而且最先被执行到;破案了,我们会看到先执行非静态代码块,在执行构造方法了;
子类同理;

最后:
日常开发中,非静态代码块使用较少,况且每次创建该类实例对象的时候都会执行,反观静态代码块,只在类加载的时候执行,切近会执行一次,孰优孰劣自有分晓。

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: