java的static块实施时机版权声明

原创
小哥 3年前 (2022-10-27) 阅读数 48 #大杂烩

1.误解:简单地想一想JAVA加载类时,会自动执行静态代码块。证据如下:
class MyClass1 {
static {//静态块
System.out.println("static block ");
}
}
public class Main {

Class[] classArray = {
MyClass1.class//这种对类的引用必然需要将类加载到虚拟机中。
};
public static void main(String[] args){
System.out.println("hello word");
}

}
执行结果:无输出" static bolck"
2.积极的解决方案:static块的实际执行时间。如果你明白的话JVM原则上,我们知道一个类的操作分为以下几个步骤:

装载
连接
初始化
其中,加载阶段由三个基本动作组成:

表示该类型的二进制数据流由该类型的完全限定名生成。
将此二进制数据流解析为方法区域中的内部数据连接。
该构造创建该类型的表示形式。java.lang.Class类的实例
此外,如果类装入器遇到缺失或不正确的class文件,该文件需要等待,直到程序第一次主动使用该类来报告错误。

连接阶段分为三个部分:

验证类型是否与Java语言的语义,检查类之间的二进制兼容性(比如final类没有子类等。),您还需要验证符号引用。
准备,Java虚拟机为类变量分配内存并设置默认初始值。
解析(可选的) 在常量类型池中查找对类、接口、字段和方法的符号引用并将这些符号引用替换为直接引用的过程。

当一个类被活跃使用时,Java虚拟将对其进行初始化,并且以下六种情况处于活动状态:

在创建类的新实例时(如通过。new或反思、克隆、反序列化等)
当调用类的静态方法时
为类或接口使用静态字段时
当调用Java API中的一些反射方法,如类。Class方法,或java.lang.reflect中的类的方法
在初始化子类时
当虚拟机启动标记为启动类的类时(即,包含main该方法的类)
Java编译器收集类型的所有类变量初始化语句和静态初始化式,并将它们放入一个特殊的方法中:clinit。

实际上,static块的执行发生在“初始化”阶段。初始化阶段,jvm主要完成静态变量的初始化、静态块的执行等工作。

让我们来看看处决的情况static块的几种情况:

1、第一次new A()该过程将打印"";因为此过程包括初始化

2、第一次Class.forName("A")该过程将打印"";因为这个过程是等价的Class.forName("A",true,this.getClass().getClassLoader());

3、第一次Class.forName("A",false,this.getClass().getClassLoader())该过程不会打印""。因为false指示在加载类期间不执行初始化。如果未初始化,则不会执行。static块。

————————————————
版权声明:本文是CSDN博主「berber78“原文,跟上。 CC 4.0 BY-SA 版权协议,转载请附上原始来源链接和本声明。
原始链接:https://blog.csdn.net/berber78/article/details/46472789

版权声明

所有资源都来源于爬虫采集,如有侵权请联系我们,我们将立即删除

热门