java static块执行机制

来源:互联网 发布:tensorflow 中文文档 编辑:程序博客网 时间:2024/06/06 00:37

根据JVM原理,一个类的运行分为以下步骤:
 1.装载。这是由类加载器执行的,该步骤将查找字节码(通常在classpath所指定的路径中找,但并不是必需的),并从这些字节码中创建一个Class对象。
 2.链接。在链接阶段即将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
 3.初始化。如果该类具有超类,则对其初始化,执行静态初始化器和静态块。
1. 装载阶段又三个基本动作组成:
 (1) 通过类型的完全限定名,产生一个代表该类型的二进制数据流
 (2) 解析这个二进制数据流为方法区内的内部数据结
 (3) 构创建一个表示该类型的java.lang.Class类的实例
 
2. 连接阶段又分为三部分:
 (1)验证,确认类型符合Java语言的语义,检查各个类之间的二进制兼容性(比如final的类不用拥有子类等),另外还需要进行符号引用的验证。
 (2)准备,Java虚拟机为类变量分配内存,设置默认初始值。
解析(可选的) ,在类型的常量池中寻找类,接口,字段和方法的符号  
 (3)引用,把这些符号引用替换成直接引用的过程。
 
3. 当一个类被主动使用时,Java虚拟就会对其初始化,如下六种情况为主动使用:
 (1)当创建某个类的新实例时(如通过new或者反射,克隆,反序列化等)
 (2)当调用某个类的静态方法时
 (3)当使用某个类或接口的静态字段时
 (4)当调用Java API中的某些反射方法时,比如类Class中的方法,或者java.lang.reflect中的类的方法时
 (5)当初始化某个子类时
 (6)当虚拟机启动某个被标明为启动类的类(即包含main方法的那个类), java编译器会收集所有的类变量初始化语句和类型的静态初始化器,将这些放到一个特殊的方法中:clinit。
注意,使用“.class”的形式创建class对象的引用时,不会自动地初始化该Class对象,初始化被延迟到了对静态方法(构造器也是静态的)或者非常数静态域进行首次引用才开始执行。

下面我们看看执行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块。

参考资料:《深入Java虚拟机》

0 0
原创粉丝点击