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!”

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值