一文了解类加载机制--ClassLoader

一、什么是ClassLoader?
众所周知,当我们编写一个Java程序时,它是由几个程序组织的一个完整的Java应用程序。类文件。程序运行时,会调用程序的一个入口函数来调用系统的相关函数,而这些函数封装在不同的类文件中,所以我们经常需要从这个类文件中调用另一个类文件中的方法。如果另一个文件不存在,程序启动时,不会一次性加载程序使用的所有类文件,而是根据程序的需要通过Java的ClassLoader动态加载一个类文件到内存中,这样类文件加载到内存后才能被其他类引用。因此,ClassLoader用于将类文件动态加载到内存中。

二、其次,默认情况下,Java提供三个ClassLoader
BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中的顶层类加载器,负责加载JDK的核心类库,如rt.jar、resources.jar、charsets.jar等。

Extension ClassLoader:称为扩展类加载器,负责加载Java的扩展类库,默认加载JAVA_HOME/jre/lib/ext/下的所有jar。
App ClassLoader:称为系统类加载器,负责加载应用类路径目录下的所有jar和类文件。

注意:除了Java默认提供的三种ClassLoader,用户还可以根据需要定义自己的ClassLoader,这些自定义的ClassLoader必须继承java.lang.ClassLoader类。它还包括Java提供的另外两个ClassLoader(扩展ClassLoader和AppClassLoader),但是Bootstrap ClassLoader并不继承classloader,因为它不是一个普通的Java类,底层是C++编写的,已经嵌入到JVM内核中。当JVM启动时,引导ClassLoader会随之启动,并负责加载核心类库以及构建扩展ClassLoader和应用ClassLoaderClassLoader。

三、ClassLoader加载类的原理

1.原理介绍
类加载器使用父委托模型来搜索类。每个类加载器实例都有一个对父类加载器的引用(不是继承关系,而是包含关系)。虚拟机本身内置的引导类加载器没有父类加载器,但可以用作其他类加载器实例的父类加载器。当一个类加载器实例需要加载一个类时,它会将这个任务委托给它的父类加载器,然后再尝试亲自搜索一个类。这个过程从上到下检查。首先,顶层的引导类加载器试图加载它。如果它不加载它,它会将任务转移到扩展类加载器来尝试加载它。如果没有加载到,则转移到App ClassLoader进行加载,如果没有加载,则返回到委托的发起方,由发起方在指定的URL如文件系统或网络中加载类。如果它们都没有加载到该类中,则会引发ClassNotFoundException异常。否则,从找到的类中生成一个类定义,将其加载到内存中,最后在内存中返回该类的类实例对象。

2.为什么要用双亲委托的模式?
因为这样可以避免重复加载,所以当父类已经加载了类时,子类加载器就不需要再加载了。考虑到安全因素,让我们想象一下,如果不使用这种委托模式,我们可以随时用用户定义的String动态替换java核心api中定义的类型,这样会有很大的安全隐患。但是父委托的方式可以避免这种情况,因为String在启动的时候已经被Bootstrcp ClassLoader加载了。因此,用户定义的类加载器永远无法加载自己编写的字符串,除非您更改JDK的类加载器搜索类的默认算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值