classLoader如何加载class【双亲委托模式】_class双亲委托-程序员宅基地

技术标签: javaSE  

ClassLoader【双亲委托模式进行类加载】

它是用来加载Class文件到JVM(Java Virtual Machine(Java虚拟机)的缩写)。
以供程序使用的。我们知道,Java程序可以动态加载类定义,而这个动态加载的机制就是
通过ClassLoader来实现的。
其中有一个ClassLoader不是用Java语言所编写的,而是JVM实现的一部分,这个
ClassLoader就是bootstrap classloader(启动类加载器),这个ClassLoader
在JVM运行的时候加载Java核心的API以满足Java程序最基本的需求,其中就包括用户自
定义的ClassLoader,这里所谓的用户自定义是指通过Java程序实现的ClassLoader,
一个是ExtClassLoader,这个ClassLoader是用来加载Java的扩展API的,也就是
/lib/ext中的类。另一个是AppClassLoader,这个ClassLoader是用来加载用户机器
上CLASSPATH设置目录中的class的,通常在没有指定ClassLoader的情况下,我们自
定义的类就由该ClassLoader进行加载。
当运行一个程序的时间,JVM启动,运行bootstrap classloader,该ClassLoader加
载Java核心API(ExtClassLoader和APPClassLoader也在此时被加载),然后调用
ExtClassLoader加载扩展API,最后APPClassLoader加载CLASSPATH目录下定义的
class,这就是一个程序最基本的加载流程。
每一个自定义ClassLoader都必须继承ClassLoader这个抽象类,而每个ClassLoader
都会有一个parent ClassLoader,我们可以看一下ClassLoader这个抽象类中有一个
getParent()方法,这个方法用来返回当前ClassLoader的parent,注意,这个parent
不是指定的被继承的类,而是在实例化该ClassLoader时指定的一个ClassLoader,如果
这个parent为null,那么就默认该ClassLoader的parent是bootstrap classloa-
der,这个parent有什么用呢?

我们可以考虑这样一种情况,假设我们自定义了一个ClientDefClassLoader,我们使用
这个自定义的ClassLoader加载java.lang.String,那么这里String是否会被这个
ClassLoader加载呢?事实上,java.lang.String这个类并不是被这个ClientDef-
ClassLoader加载,而是由bootstrap classloader进行加载,为什么会这样?实际
上这就是双亲委托模式的原因,因为在任何自定义ClassLoader加载一个类之前,它都会
先委托它的父亲ClassLoader进行加载,只有当父亲ClassLoader无法加载成功后,才会
由自己加载,在上面这个例子里,因为java.lang.String是属于Java核心API的一个类,
所以当使用ClientDefClassLoader加载它的时候,该ClassLoader会先委托他的父亲
ClassLoader进行加载,当ClassLoader的parent为null时,ClassLoader的parent
就是bootstrap classloader,所以在ClassLoader的最顶层就是bootstrap 
classloader,因此最终委托到bootstrap classloader的时候,bootstrap 
classloader就会返回String的Class。

下面我们看一下ClassLoader中的一段源码:

public class Snippet{
    
 
    protected synchronized Class loadClass(String name,boolean resolve) throws
        ClassNotFoundException{
    
        //首先检查该name指定的class是否被加载
        Class c = findLoadedClass(name);
        if(c==null){
    
            try{
    
                if(parent!=null){
    
                //如果parent不为null,则调用parent的loadClass进行加载
                c=parent.loadClass(name,false);
                }else{
    
                //如果parent为null,则调用BootstrapClassLoader进行加载
                c=findBootstrapClass0(name);
                }
       }catch(ClassNotFoundException e){
    
            //如果仍然无法加载成功,则调用自身的findClass进行加载
            c=findClass(name);
        }
  }
        if(resolve){
    resolveClass(c);}
        return c;
 }             
}

从上面的一段代码,我们可以看出一个类加载的大概过程,与我们刚开始所举的例子是一样的,而我们要实现一个自定义类的时间,只需要实现findClass方法即可。
为什么要使用这种双亲委托模式呢?
1:避免重复加载,当父亲已经加载过该类的时候,就没有必要再加载一次了
2:考虑到安全因素,试想一下,如果不使用这种模式,我们可以随时的用自定的String来动态替代java核心API中定义类型,这样存在非常大的安全隐患

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/g_l_xz/article/details/103331013

智能推荐

mysql竖表转横表,横表转竖表_mysql竖表变横表-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏9次。SELECT p.姓名p.语文,p.数学,p.英语 from score as a pivot(sum(成绩) for 课程 in(语文,数学,英语)) as p;查询第一行数据,当查询课程列的内容为'语文'时候,then'语文'这个值变为它对应成绩值60,起列名为语文。--竖表转行表使用pivot(这个是sqlserver,mysql不可以使用)第二行数据,课程值为‘数学’时,then'数学'变为70,起列名为数学。无论是横转竖,还是竖转横,原表都不变还是原来的样子。score2,此表为横表。_mysql竖表变横表

【编程马拉松】【019-一笔画】_一笔作画游戏 csdn-程序员宅基地

文章浏览阅读2.6k次。咱们来玩一笔画游戏吧,规则是这样的:有一个连通的图,能否找到一个恰好包含了所有的边,并且没有重复的路径。输入包含多组数据。每组数据的第一行包含两个整数n和m (2≤n, m≤1000),其中n是顶点的个数,m是边的条数。紧接着有m行,每行包含两个整数from和to (1 ≤ from, to ≤ n, from != to),分别代表边的两端顶点。边是双向的,并且两个顶点之间可能不止一条边_一笔作画游戏 csdn

我的隐私计算学习——联邦学习(5)-程序员宅基地

文章浏览阅读963次,点赞19次,收藏22次。联邦迁移学习与值得关注的联邦学习项目、应用方向

每天写bug是一种怎样的体验?_写bug呢-程序员宅基地

文章浏览阅读2.1w次,点赞13次,收藏23次。点击上方“程序员小灰”,选择“置顶公众号”有趣有内涵的文章第一时间送达!本文转载自公众号 小象源 | 小象 文 | 小象君“哥们,又在写bug呢?”据说这是对程序员杀伤力最大的一句话没有之一!之所以如此,那是因为这是句大实话啊!程序员的人生就是bug和debug交织在一起的悲歌尽管每天都要和Bug打交道可你是否知道Bug这个叫法是怎么来的吗?上图中那个黑乎乎的东西就是史上第一个程序Bug_写bug呢

分糖问题_solo和koko是两兄弟-程序员宅基地

文章浏览阅读5.5k次,点赞6次,收藏22次。问题描述Solo和koko是两兄弟,妈妈给了他们一大袋糖,每块糖上都有自己的重量。现在他们想要将这些糖分成两堆。分糖的任务当然落到了大哥Solo的身上,然而koko要求必须两个人获得的糖的总重量“相等”(根据Koko的逻辑),要不然就会哭的。非常不幸的是,koko还非常小,并且他只会先将两个数转成二进制再进行加法,而且总会忘记进位。如当12(1100)加5(101)时: &nbs..._solo和koko是两兄弟

数据结构与算法学习笔记2:栈和队列_一万个括号-程序员宅基地

文章浏览阅读374次。数据结构与算法学习笔记2栈 stack堆和栈的区别静态变量tips跨文件使用tips:关键字extern指针传递队列 queue队列类型:单端队列:循环队列:**r+1%n**?**循环队列如何判断队列为空or为满?**栈和队列 相关题目括号匹配问题约瑟夫环问题队列和栈的相互转换栈 stack受限线性表先进后出 FILO题外话:堆和栈是内存区域的问题,栈和队列是数据结构的问题,两者没有任何关系。堆和栈的区别申请空间的方式和回收不一样。堆区的空间要向系统申请,malloc和new,_一万个括号

随便推点

vue项目实现导航栏吸顶功能_vue吸顶导航栏-程序员宅基地

文章浏览阅读478次。建立判断条件,如果页面滚动的值超过导航栏的高度navHeight时,将导航栏的position属性值改为fixed,top值可以设置为0px。当页面回到顶端时,需要再次显示为原来默认的状态,所以把导航栏的position值改为默认的static。调用窗口滚动对象window.onscroll事件。当滚动页面的滚动条时会触发scroll里的事件方法。_vue吸顶导航栏

Visual Studio 2008简体中文试用版(90天)变成永久正式版的两种方法-程序员宅基地

文章浏览阅读176次。Visual Studio 2008简体中文试用版(90天)变成永久正式版的两种方法: 一、先安装试用版,然后在“添加或删除程序”里找到VS2008,点“更改/删除”就会看到一个输入序列号的地方,把序列号输进去,点“升级”按钮即可,Team Suite和Professional通用。 二、用UltraISO打开VS的ISO安装文件,把Setup\setup.sdb文件解压缩出来,一定记得..._xmq2y4t3v6xj48yd3k2v6c4wt

Ubuntu Server内核优化提高并发_ubuntu server 系统优化-程序员宅基地

文章浏览阅读3.1k次。设置文件打开句柄数# 查看系统默认的值ulimit -n# 设置最大打开文件数ulimit -n 1000000这样只能在当前 shell 中有效。通过修改配置文件的方式修改程序最大打开句柄数可以永久有效:sudo vim /etc/security/limits.confroot soft nofile 1040000root hard nofile 1040000..._ubuntu server 系统优化

【考研数学】零基础跟「张宇」的几点体会-程序员宅基地

文章浏览阅读302次,点赞3次,收藏8次。(比如我也听了武忠祥老师的课,不得不说某些方法确实让人拍手叫绝,但是一看题呢,该不会的还是不会。这些阶段如果保质保量的完成,在考试里大致对应的分数是 0,80,120,130。但很多人不知道展开到几项,哪些是可以扔掉的,把很简单的题算得很复杂,有的还背了很多不必要的技巧,纯属浪费时间。入门,基础,强化,是递进关系,不能越级!综测会一直持续到备考结束,也就是说将近一年的时间里,它都会通过滚动复习,让你持续保持火热的手感~真的是保姆级了!根据你自己的薄弱低点,针对性地练,哪里不会练哪里,才能吃透,而且省时间。

【翻译+理解】Channel Access Protocal——EPICS Base-3.16版CA协议 - 基本概念_epics ca协议-程序员宅基地

文章浏览阅读2k次。参考文献:1. 官方CA协议说明 https://epics.anl.gov/base/R3-16/1-docs/CAproto/index.html#_concepts(本翻译的原文)2. EPICS培训PPT EPICS_Introduction_PSI2011.ppt https://download.csdn.net/download/u013894429/10823381(找不到..._epics ca协议

基于java和微信小程序的 点餐外卖小程序-后台Java 毕业设计毕设源码最终作品_java外卖小程序源码-程序员宅基地

文章浏览阅读2.2k次,点赞3次,收藏13次。微信小程序在线点餐外卖系统主要包含功能:微信登录、普通用户注册和登录、用户信息修改、用户密码修改;用户首页、菜品分类、产品浏览、增加数量、减少数量、订餐、收藏、地址管理、评论、广告设置等;提供项目源代码(小程序+接口+后台)。开发工具:IDEA2020开发环境:JDK1.8 +Tomcat8数据库:Mysql8小程序后台..._java外卖小程序源码