详解类的加载过程

类加载主要职责就是加载各种 class 文件到 JVM 中,
类的加载过程主要分为三个阶段:加载、连接、初始化
其中连接又分为:验证、准备、解析三个过程
在这里插入图片描述

加载

类的加载就是将class文件中的二进制数据读取到内存中,然后将该字节流锁代表的静态存储结构转换为方法区中运行时的数据结构,并且在堆内存中生成一个该类的java.lang.Class 对象,作为访问方法区数据结构的入口。

连接

1. 验证

验证阶段主要是确保class文件的字节流锁包含的内容符合当前 jvm 规范的要求,并且不会出现危害 jvm 自身安全的代码,如果不符合要求则会抛出 VerifyError 这样的异常或其子异常

验证信息

  • 文件格式
  • 元数据验证
  • 字节码验证
  • 符号引用验证

2. 准备

字节流通过验证后,会为该对象的类变量(也就是静态变量)分配内存并且设置初始值,类变量的内存会被分配到方法区中,不同于实例变量会被分配到堆内存中
这里的设置初始值就是为类变量给定一个该类型的默认值
在这里插入图片描述
注意:final 修饰的静态变量可以直接计算得出结果,不会导致类的初始化,是一种被动引用,所以不需要连接

3. 解析

解析会交叉一些验证的过程,解析就是在常量池中寻找类、接口、字段和方法的符号引用,并且将这些符号引用替换成直接引用的过程。

  • 符号引用:
    符号引用以一组符号来描述所引用的目标, 符号可以是任何形式的字面量, 只要使用时能够无歧义的定位到目标即可. 例如, 在Java中, 一个Java类将会编译成一个class文件. 在编译时, Java类并不知道所引用的类的实际地址, 因此只能使用符号引用来代替.
    举个例子:org.simple.People类引用了org.simple.Language类, 在编译时People类并不知道Language类的实际内存地址, 因此只能使用符号org.simple.Language来表示Language类的地址.

  • 直接引用:
    直接引用和虚拟机的布局是相关的,不同的虚拟机对于相同的符号引用所翻译出来的直接引用一般是不同的。如果有了直接引用,那么直接引用的目标一定被加载到了内存中

初始化阶段

初始化阶段主要是给类变量中赋予代码中定义的初始值而不是变量类型的默认值

JVM主动使用类的六种场景

  • 通过new 关键字会导致类的初始化

  • 访问类的静态变量,包括读取和更新会导致类的初始化

public class test {
		static {
			System.out.println("I'mhere");
		}
		public static int x=10;
		
		public static void  main(String[]  args){
			System.out.println("ok");
		}
	}

x是简单的静态变量,其他类即使不对Simple进行new的创建,直接访问变量x也会导致类的初始化

  • 访问类的静态方法,也会导致类的初始化
	public class test{
		static{
			System.out.println("I will be inisialized");
		}
		public static void a(){
		
		}
		public static void main(String[]args){
			System.out.println("ok");
		}
	}
  • 对某个类进行反射操作,会导致类的初始化
public static void main(String[]  args) throws  ClassNotFoundException{
	Class.forName("com.xinling.ToolsDemo.CountryEnum");
}

运行这段代码也能看到静态代码块中的输出语句

  • 初始化子类会导致父类初始化
  • 启动类:执行main函数所在的类会导致该类初始化

除了上述6种情况,其余的都被称为被动使用,不会导致类的加载和初始化

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值