当前位置:   article > 正文

Java虚拟机四:类加载机制_getstatic、pubstatic

getstatic、pubstatic

虚拟机把描述Class文件加载到内存,并对数据进行校检、转换解析、初始化,最终形成可以被虚拟机使用的Java类型,将这个过程称之为类的加载机制。

一、类的加载过程

类从被加载到内存开始,会经历加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)、和卸载(Unloading)这7个阶段,其中验证、准备和解析3个统称为连接(Linking)。

这里写图片描述

其中加载、验证、准备、初始化和卸载这5个接口的顺序是确定的,但是解析阶段是不一定的,因为java语言的动态绑定。

1。加载(Loading) :

加载阶段虚拟机要完成3件事情:

1。通过一个类的全限定名来获取定义此类的二进制流。

2。将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

3。在内存中生成一个代表这个类的Class对象,作为方法区这个类的各种数据的访问入口。

类的加载时机
Java虚拟机规范中并没有强制约束什么时候开始进行加载。但是对于初始化阶段,虚拟机规范严格规定了“有且只有5种情况必须立即对类进行初始化”,而加载、验证、准备肯定是在初始化之前要做的,那其实也间接的约束加载,也可以理解为类的加载时机。

1。遇到new、getstatic、pubstatic或invokestatic这4条字节码指定时,如果类没有进行初始化,需要先初始化。这4个指令对应Java代码的场景分别是:使用new关键字创建对象时、读取或者设置一个类的静态自动(不被final修饰的)、调用一个类的静态方法时。

2。使用java.lang.reflect包中的方法对类进行反射调用时,如果没有初始化先初始化。

3.。当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。

4。当虚拟机启动时,用户指定一个要执行的主类,就是程序的入口,带main方法的类,那么要先初始化这个主类。

5。当使用JDK1.7的java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这和对应的类有没初始化,要先触发初始化。

上边5中叫做主动引用,除了这5种情况其他引用类的情况不会被初始化,也叫做被动引用。

被动引用例子1:

/**
*被动使用类字段演示一:
*通过子类引用父类的静态字段,不会导致子类初始化
**/
public class SuperClass{
   
    static{
        System.out.println("SuperClass init!");
    }

    public static int value=123;
}
/**
*子类
**/
public class SubClass extends SuperClass{
   
    static{
        System.out.println("SubClass init!");
    }
}

/**
*非主动使用类字段演示
**/
public class No
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/代码探险家/article/detail/1006997
推荐阅读
相关标签
  

闽ICP备14008679号