Class文件的加载过程和类加载器的原理

本文详细介绍了Java中Class文件的加载过程,包括loading、linking(verification、preparation、resolution)、initializing阶段。类加载器(ClassLoader)分为Bootstrap、Extension、App和Custom四类,并遵循双亲委派模型。该模型确保了安全性和效率,但可以通过重写loadClass方法打破此机制。此外,还讨论了自定义类加载器的实现和配置路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Class 文件是怎样被放在内存的

在这里插入图片描述
硬盘中的Class被加载的过程
1、loading
把一个class 加载到内存,懒加载,需要的时候再加载
2、linking
(1)、verification
校验class,是否满足class的格式
(2)、preparation
把class中静态变量设置成默认值 int类型 0
(3)、resolution
解析 loadeClass方法中的第二个参数 true 为解析 false 不解析
class中常量池用到的符号引用转换成可以直接访问内存的值(直接能访问到的内容)
即 将类、方法、属性等符号引用解析为直接引用
常量池中的各种符号引用解析为指针、偏移量等内存地址的直接引用
3、initializing
静态变量的赋值,赋值为初始值,调用静态变量块
在类初始化代码,给静态成员变量赋初始值
Class:load 默认值 初始化
new:申请内存 默认值 初始值

类加载器(ClassLoader)

jvm有一个类加载器的层次,分别加载不同的class
jvm中所有的class 都是被类加载器加载到内存的
一个class 被 load 到内存后, 内存中创建了两块内容
一块是将class对应的二进制内容扔进 内存中 ,同时也生成了一个class类的对象并指向二进制文件,这个对象保存在mataspace中
别的对象访问这个类的时候就是通过访问生成的这个Class类对象,然后这个class类对象再去访问二进制文件
即访问过程是 通过访问class文件对应创建的class类,然后class类从指向的二进制中获取对应二进制并解析成汇编指令
如下是获取类对应加载器的部分示例

public class T002_ClassLoaderLevel {
   
   
    public static void main(String[] args) {
   
   
		// null---Bootstrap ClassLoader  
		// 返回null的原因:Bootstrap ClassLoader 是由C++实现的,java中没有对应的class 所以返回空
		// 可以理解成c++实现的一个模块
        System.out.println(String.class.getClassLoader());  
		//null---Bootstrap ClassLoader
        System.out.println(sun.awt.HKSCS.class.getClassLoader());  
		//sun.misc.Launcher$ExtClassLoader@6d6f6e28 --- Extension ClassLoader
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader());  
		//sun.misc.Launcher$AppClassLoader@18b4aac2 --- App ClassLoader
        System.out.println(T002_ClassLoaderLevel.class.getClassLoader());
		// null   父加载器不是 加载器的加载器     所以   classLoader 的 classloader 都是null
        System.out.println(sun.net.spi.nameservice.dns.DNSNameService.class.getClassLoader().getClass().getClassLoader());
		// null  同上   ClassLoader 本身就是c++ 写的
        System.out.println(T002_ClassLoaderLevel.class.getClassLoader().getClass().getClassLoader());
		// sun.misc.Launcher$ExtClassLoader@6d6f6e28 --- T002_ClassLoaderLevel 的类加载器是APP APP的父加载器是 Ext加载器
        System.out.println(new T002_ClassLoaderLevel().getParent());
        System.out.println(ClassLoader.getSystemClassLoader());
    }
}

加载器分类

在这里插入图片描述
Bootstrap: jdk 加载核心类的类加载器
Extension: 是加载扩展包中的的
App: 加载classpath 指定的类的,即加载我们自己写的类
Custom: 自定义的类加载器

Class 类加载器加载过程

双亲委派: 从子到父的过程和从父到子的过程
过程: class首先会从 Custom加载器(缓存 ——每个类加载器 维护一个list 用来管理已经加载的对象引用)中找,找到返回结果,找不到会从上层加载器APP中找,如果还是找不到再到Ext加载器中招,一直到Bootstrap加载器,(前面的find 都是从缓存中找),如果缓存中没有,则find class 并加载,如果 bootstrap没有加载到,则交给下一层加载器 ext find class 并加载 ,直到custom 。如果custom 没有找到class,则报错 ClassNotFoundException异常
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值