Java静态代码块执行时机


​ 百度一下java的static块执行时机,搜出来的文章有两种说法,第一种说static块是在类的加载时执行(包括我看过的Java视频都是这么说的),另一种则是反对第一种说法,即static块并不是在类的加载时执行的,而是在类的初始化时执行的;谁对谁错,事实用代码证明。

类的运行步骤

​ 类的运行可分为三个步骤:装载、连接、初始化

  • 装载:查找和导入Class文件
  • 连接:把类的二进制数据合并到JRE中,又分为三个步骤
    • 校验:检查载入Class文件数据的正确性
    • 准备:给类的静态变量分配存储空间
    • 解析:将符号引用转成直接引用
  • 初始化:对类的静态变量,静态代码块执行初始化操作(看到这里,结论就已经出来了,但我们还是要用代码来说话)

用反射机制来证明static块的执行时机

  • 有一个含static块的类:
class MyStatic {
    static {
        System.out.println("静态代码块执行了");
    }

    MyStatic() {}
}
  • 先来看一个错误的例子(我看的视频里就是用这个例子来证明static块是在类的加载时执行的)
public class Test {
    public static void main(String[] args) {
      	Test test = new Test();
        try{
            Class.forName("MyStatic");  //误认为forName方法运行类只完成加载,实际上forName方法运行时已执行了类的初始化
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

​ 运行结果

静态代码块执行了

​ 静态代码块执行了,然而这并不能代表什么,因为

Class.forName("MyStatic");

​ 等同于

Class.forName("MyStatic", true, test.getClass().getClassLoader());

​ 其中第二个参数指明了是否进行类初始化,将其改成false再试一次

public class Test {
    Test() {}
    public static void main(String[] args) {
        Test test = new Test();
        try{
            Class.forName("MyStatic", false, test.getClass().getClassLoader());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

​ 这时MyStatic类并没有进行初始化过程,而程序运行没有任何输出,得出结论:

Java中静态代码块是在类的初始化过程中执行的,并不是在类的装载时执行的


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM