JVM类加载时机
类加载过程简述:Java虚拟机把描述类的内容从class文件中加载到虚拟机内存中,对其校验、转换解析、初始化。最终形成可以被虚拟机直接使用的java类型,此过程成为虚拟机的类加载过程类加载时机类的生命周期:虚拟机中类的生命周期从被加载到虚拟机内存中开始,卸载出内存为止。总共包括:加载、验证、准备、解析、初始化、使用和卸载7个阶段。其中验证、准备、解析三阶段被称为连接阶段...
·
类加载过程简述:
Java虚拟机把描述类的内容从class文件中加载到虚拟机内存中,对其校验、转换解析、初始化。最终形成可以被虚拟机直接使用的java类型,此过程成为虚拟机的类加载过程
类加载时机
类的生命周期:
虚拟机中类的生命周期从被加载到虚拟机内存中开始,卸载出内存为止。总共包括:加载、验证、准备、解析、初始化、使用和卸载7个阶段。其中验证、准备、解析三阶段被称为连接阶段。
各阶段执行时机:
加载、验证、准备、初始化、卸载五个阶段的执行顺序是固定不变的,其中加载、验证、准备三步必须在初始化之前开始,解析阶段可能会在初始化之后开始。这些阶段通常都是交叉混合进行的,可能在执行一个阶段时会激活、调用其他阶段。
主动引用:
Java虚拟机规范中并未规定何时开始执行加载阶段,但是有6种情况下必定会触发初始化阶段。
- 遇到new、getStatic、putStatic、invokeStatic四个指令时,若该类未初始化则触发其初始化。以下为典型场景:
- 使用new指令对类实例化时
- 调用、设置一个类型的静态字段时(被final修饰过的或者在编译阶段就将结果存入常量池中的静态字段除外)
- 调用一个类型的静态方法时
- 使用java.lang.reflect包中的方法对类进行反射调用时,若该类未初始化则触发其初始化
- 对类进行初始化时先检查该类父类是否初始化,若未初始化则触发其初始化
- 虚拟机启动时,需要用户指定一个主类,并将其初始化(包括main()的类)
- JDK7时,如果一个java.lang.invoke.MethodHandle实例的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic、REF_newInvokeSpecial四种方法句柄时,如果该句柄所对应的类未初始化则触发其初始化
- 如果一个接口中的方法被定义为JDK8中的默认方法(被default所修饰的方法)时,若该接口的实现类即将初始化则需先将该类进行初始化
被动引用:
有且仅有以上6种情况会对类进行主动初始化,除此之外的所有类型都不会被主动初始化
- 子类引用父类的静态字段,不会触发子类的初始化
- 用数组定义的引用类,该引用类不会触发初始化
- 常量在编译阶段时存入调用类的常量池中,并没有直接引用定义常量的类,不会对定义常量的类触发初始化
类和接口加载时的区别
上述所说的类描述比较笼统,实际上在接口加载时与类加载时是有所区别的,在有且仅有的6中主动引用中的第三种:在对类进行初始化之前,先对其父类进行初始化,在对接口初始化时,不会强制其所有父接口初始化,只有用到这个父接口时才会对其初始化
更多推荐
已为社区贡献7条内容
所有评论(0)