Java 类加载过程

本文详细解析了Java类加载的完整流程,包括加载、验证、准备、解析、初始化和卸载,重点讲解了验证阶段的自我保护机制,以及类加载器和双亲委派机制的工作原理。了解类加载如何确保安全并高效地加载和组织类的生命周期。
摘要由CSDN通过智能技术生成

类加载

1.1 类加载过程

“.java”后缀的文件打包成“.jar”后缀的jar包或后缀为“.war”的war包,打包的过程中一般会把“.java”的文件编译成“.class”后缀的字节码文件。

JVM要运行这些“.class”字节码文件中的代码,就需要类加载器把编译好的那些“.class”字节码文件给加载到JVM中,然后供后续代码运行来使用。

当代码中用到这个类的时候,才会去加载这个类。一个类从加载到使用,一般会经历下面的这个过程:

加载 -> 验证 -> 准备 -> 解析 -> 初始化 -> 使用 -> 卸载

(1)验证阶段

​ 确保加载的字节码的是否符合虚拟机的要求,是java提供的一种自我保护机制,不让其危害虚拟机安全。其主要包括四种验证,字节码验证、文件格式验证,元数据验证、符号引用验证。

(2)准备阶段

​ 给类分配一定的内存空间,然后给类里面的类变量分配内存空间,并赋一个初始值。类变量会分配到方法区中,这里的初始化是指该数据类型的默认初始值,例如int对应的是0,long对应的0L,只有在初始化时才会动显示赋值

(3)解析阶段

​ 把类中的二进制数据中的符号引用转换为直接引用;例如我们通过XXX.abc();这里的.abc()就是符号引用,在解析阶段会将它指向真正的内存位置,这就是直接引用

(4)初始化阶段

​ 在初始化阶段,就会执行类的初始化代码了。类变量的赋值操作、静态代码块的执行等。

什么时候会初始化一个类?一般来说有以下一些时机:

  1. 当实例化类的对象时(new),此时就会触发类的加载到初始化的全过程,把这个类准备好,然后再实例化一个对象出来;
  2. 包含“main()”方法的主类,必须是立马初始化的。
  3. 如果初始化一个类的时候,发现他的父类还没初始化,那么必须先初始化他的父类

1.2 类加载器和双亲委派机制

1.2.1 类加载器

1.引导类加载器(Bootstrap ClassLoader)
用来加载 Java 的核心库,是用原生代码(C语言)来实现的,并不继承自 java.lang.ClassLoader。

1.扩展类加载器(Extensions ClassLoader)
用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java类。

3.应用程序类加载器(Application ClassLoader)
它根据 Java 应用的类路径(classmate,java.class.path 路径下的内容)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。

4.自定义类加载器(Custom ClassLoader)
开发人员可以通过继承 java.lang.ClassLoader类的方式实现自己的类加载器,以满足一些特殊的需求。

1.2.2 双亲委派机制

​ Java虚拟机对class文件采用的是按需加载的方式,也就是说当需要使用该类时才会将它的class文件加载到内存生成class对象,而且,加载某个类的class文件时,Java虚拟机采用的是双亲委派机制,即把请求交由父类处理,它是一种任务委派模式

​ 过程:

(1)如果一个类加载器收到了类加载请求,它并不会自己先加载,而是把这个请求委托给父类的加载器去执行

(2)如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的引导类加载器;

(3)如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会尝试自己去加载,这就是双亲委派机制

(4)父类加载器一层一层往下分配任务,如果子类加载器能加载,则加载此类,如果将加载任务分配至系统类加载器也无法加载此类,则抛出异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值