详解Java中的类加载器以及机制

本文深入探讨Java的类加载机制,包括平台无关性、类加载器的种类与职责,以及双亲委派机制如何避免重复加载。同时,解析了类加载的三个阶段:加载、链接和初始化,并对比了forName()与loadClass()方法的不同应用。

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

我们都知道Java的平台无关性是其一大特点,所谓平台无关性是指Java的源码会被编译成Class字节码文件,其字节码文件可以被不同平台上的JVM所解析然后执行,从而实现跨平台性。那么这一过程是具体是如何实现的呢?

类加载器

类加载器(ClassLoader),顾名思义就是专门用来加载类的,其作用就是将编译好的Class文件加载到JVM中。在Java中默认提供类三种类加载器:

  • Bootstrap ClassLoader   这个加载器主要负责加载Java中核心包,例如java.lang.*
  • ExtClassLoader  这个加载器主要负责加载Java中的扩展包,例如javax
  • AppClassLoader  这个加载器主要负责加载应用程序主程序类

同时,也可以自定义ClassLoader。通过类加载器,可以将我们的Class字节码文件转化为相应的二进制字节流到JVM中。那么此时就会出现一个问题,一个Class字节码文件该由哪个类加载器来执行呢?

 

双亲委派机制

双亲委派机制就是为了解决多个加载器重复解析同一个字节码文件,其机制如下图:

当有一个出现Class字节码文件时,首先交由自定义加载器看是否加载,如果加载了则不继续提交给父加载器,如果不加载则提交给父加载器AppClassLoader。同样如果AppClassLoader不加载则继续提交给其父加载器ExtClassLoader,如果ExtClassLoader还是不加载则最终提交给Bootstrap ClassLoader。此过程自底向上。

然后Bootstrap ClassLoader开始从尝试加载此字节码文件,如果它表示无法加载,则向下转交给子加载器。以此类推,如果最终自定义类加载器也无法加载此字节码文件则抛出异常。此过程自顶向下。

此流程即为双亲委派机制,通过这个机制可以有效的避免对字节码文件的重复加载。

 

类加载机制

类加载过程主要分为以下三个过程:

 

之前,通过类加载器实现了第一步,加载过程。

接着,用户想要拿到JVM中的Class对象,有两种方法,一种为forName()方法,一种为loadClass()方法,其过程完全不同。

forName()的实现过程:

Class test = Class.forName("Test");

 直接通过Class的静态方法可以获取想要的对象,此过程会自动实现链接和初始化阶段。

loadClass()的实现过程:

ClassLoader cl = Test.class.getClassLoader();
Class test = cl.loadClass("Test");

首先获取处理该字节码的类加载器,然后通过类加载器生成用户想要的对象,和forName()方法不同的是此方法只完成了加载阶段,并没有实现链接和初始化阶段。那么这种方法有什么应用场景呢?在Spring中,可以loadClass()方法实现一种加载方式—懒加载。只将类加载到JVM中,只有当该类真正用到的时候才会被检查和初始化,这样可以大大的提高运行的效率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值