JVM加载class文件的过程
作者:bin加载class的过程是:装载、链接、初始化
java类在以下场景一定会被加载:
1、遇到new、get static、put static、invoke static时如果当前类没有被初始化,则先除法初始化
2、使用反射java.lang.reflect包方法进行反射调用时,会进行初始化
3、初始化一个类时,如果父类没初始化,父类也会被初始化
4、虚拟机启动时,用户指定一个主类,即包含main方法的那个类,会被初始化
关联知识:双亲委派模型
———一图读懂:
我们用如下类做测试:
import java.lang.*; public class test { /** * clinit是class类构造器对静态变量,静态代码块进行初始化 * 其中静态代码块 和 静态变量,加载的顺序是根据编码顺序来的 */ static { System.out.println("clinit()执行,准备阶段为静态变量赋予了初始值:" + test.staticVariable + ",同时验证了执行顺序"); } /** * <clinit执行> 静态变量 */ static String staticVariable = "静态变量"; // <clinit> /** * <clinit执行> 静态代码块 */ static { System.out.println("clinit()执行,静态代码块:" + staticVariable); } /** * <init执行> 非静态代码块 */ { System.out.println("init()执行,初始化是为:" + this.simpleVariable + ",同时验证了执行顺序"); } /** * init是instance实例构造器,对非静态变量解析初始化 */ /** * <init执行> 非静态变量 */ private String simpleVariable = "非静态变量"; /** * <init执行> 非静态代码块 */ { System.out.println("init()执行,非静态代码块:" + simpleVariable ); } /** * <init执行> 构造方法 */ test(){ System.out.println("init()执行,构造方法:" + simpleVariable); } public static void main(String[] args) { test t = new test(); } }
输出:
clinit()执行,准备阶段为静态变量赋予了初始值:null,同时验证了执行顺序 clinit()执行,静态代码块:静态变量 init()执行,初始化时为:null,同时验证了执行顺序 init()执行,非静态代码块:非静态变量 init()执行,构造方法:非静态变量