Java虚拟机类加载机制(一)——类加载的时机

虚拟机如何加载Class文件?
Class文件里的信息进入虚拟机会发生怎样的变化?

虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是类加载机制

类加载的时机

类从被加载到内存到卸载出内存,生命周期:
加载、连接(验证、准备、解析)、初始化、使用、卸载
初始化

  1. 遇到new、getstatic、putstatic或invokestatic,若类未初始化,则触发初始化
  2. 使用java.lang.reflect对类进行反射调用
  3. 父类没有进行过初始化,先初始化父类
  4. 虚拟机启动时,先初始化要执行的主类
  5. 若java.lang.invoke.MethodHandle实例最后的解析结果为REF_getStatic、REF_putStatic、REF_invokeStatic的句柄,若此方法句柄对应的类没有进行过初始化,则要先初始化。

下面以代码来演示

//父类superClass
public class SuperClass {
	static {
		System.out.println("SuperClass init!");
	}
	public static int sup = 1111111;
}
//子类subClass
public class subClass extends SuperClass{
	static {
		System.out.println("SubClass init!");
	}
	public static int sub = 2222222;
}

在这里插入图片描述
guess结果是啥?

分析,参考上面规则的第三条: 3. 父类没有进行过初始化,先初始化父类
首先是subClass.sub:要调用子类中的静态变量sub,那就要初始化子类,但是在子类初始化之前,还要去先初始化父类,最后才打印sub的值
在运行第二句时,两个类已经经过初始化,那么直接打印值即可。
在这里插入图片描述

public static void main(String[] args) {
		SuperClass[] sca = new SuperClass[10];;
	}

这样,并没有输出superClass init!
它代表了元素类型为superClass的一维数组,它是继承于java.lang.Object的子类

public class ConstClass {
	static{
		System.out.println("ConstClass init!");
	}
	public static final String Hello = "Hello!";
}
public class NotInitialization {
	public static void main(String[] args) {
		System.out.println(ConstClass.Hello);
	}
}

输出什么?
Hello!在这里插入图片描述
为啥没有执行static里面的语句呢???
这里用了final,即Hello是常量,它被存放在常量池中,和ConstClass这个类没有了联系,主函数在执行时,不需要对ConstClass类进行初始化,所以最终只打印“ Hello!”

发布了45 篇原创文章 · 获赞 14 · 访问量 2463

猜你喜欢

转载自blog.csdn.net/qq_44357371/article/details/104069757