关于JAVA的类加载器,网上有很多这方面资料,这里只做测试,不多累述。JVM有三个内置加载器:           bootstrapClassLoader(由C语言编写,固化在jvm上)、ExtClassLoader、AppClassLoader。三个加载器从上到下呈父子关系,形成了“类加载委托模型”:即儿子的事情,父亲能做的,他一定会代劳(以免累到儿子),父亲的事情,一定会自已做,即使自已无法完成,也不会劳及儿子。三个类的加载路径分别为(更多细节参考google):

BootstrapClassLoader:    sun.boot.class.path 
ExtClassLoader:     java.ext.dirs                                                                                   AppClassLoader:     java.class.path

首先定义两个类:

  1. package loader;
  2. public class ClassA {
  3. public static void main(String args[]){
  4. System.out.println("ClassA: " + ClassA.class.getClassLoader());
  5. ClassB a = new ClassB();
  6. System.out.println("ClassB: " + ClassA.class.getClassLoader());
  7. }
  8. }
  9. //
  10. package loader;
  11. public class ClassB {
  12. }

拷贝三份到:C:\Java\jre6\classes(bootstrapClassLoader的搜索目录之一),C:\Java\jre6\lib\ext\classes(extClassLoader的搜索目录之一),F:\javawork\study\bin目录下,其中C:\Java\jre6为我JRE目录。一定不要搞错,因为你的机器可能会有很多JRE。

CMD到F:\javawork\study\bin目录

1. F:\javawork\study\bin>java loader.ClassA
ClassA: null
ClassB: null

两个都为空,这是因为当AppClassLoader(默认的系统类加载器)来加载CLASSA,首先委托其父ExtClassLoader去加载,然后AppClassLoader委托bootstrapClassLoader去加载,bootstrapClassLoader没有父加载器,只能自已完成,在自已加载目录C:\Java\jre6\classes下找到了CLASSA,加载成功。然后CLASSA的加载器bootstrapClassLoader加载CLASSB,同样在C:\Java\jre6\classes找到CLASSB,所以两个类的加载器都是bootstrapClassLoader,因为bootstrapClassLoader实现于C++,所以返回NULL。

2. 删除C:\Java\jre6\classes目录下的CLASSB

F:\javawork\study\bin>java loader.ClassA
ClassA: null
Exception in thread "main" java.lang.NoClassDefFoundError: loader/ClassB
        at loader.ClassA.main(ClassA.java:6)

这是因为同(1)一样,最后由bootstrapClassLoader成功加载CLASSA,然后由CLASSA(这里叫CLASSB的CALLER)的加载器bootstrapClassLoader需要去加载CLASSB,但bootstrapClassLoader尽其力也没能找到(因为被我删了),这位慈爱的父亲到最后一刻都没有交给儿子ExtClassLoader去做,最后上报:我无能为力。

3.把(2)中删除的CLASSB还原,同时删创除该目录下的CLASSA

F:\javawork\study\bin>java loader.ClassA
ClassA: sun.misc.Launcher$ExtClassLoader@126b249
ClassB: null

两个都输出ExtClassLoader,顺着(1)的思路,AppClassLoader委托ExtClassLoader,ExtClassLoader委托bootstrapClassLoader,bootstrapClassLoader找不到CLASSA,只能放手让儿子去做(比如找女朋友这事,小伙子本来想老爸战友的女儿不错,可父亲去提亲,人家不应,“不行,儿子,你自个追其他的吧!”)。ExtClassLoader绝地逢生,在自已的区域内找到了CLASSA。然后CLASSA的加载器ExtClassLoader去加CLASSB, 同样道理这事交给老爸bootstrapClassLoader去做,bootstrapClassLoader责无旁贷,顺利完成,所以ClassB: null。

4.把(3)中剩下的CLASSB也删除。

F:\javawork\study\bin>java loader.ClassA
ClassA: sun.misc.Launcher$ExtClassLoader@ad3ba4
ClassB: sun.misc.Launcher$ExtClassLoader@ad3ba4

同(1)一样,ExtClassLoader绝地逢生,在自已的区域内找到了CLASSA,然后CLASSA的加载器ExtClassLoader去加CLASSB,不幸的事,这次老爸bootstrapClassLoader却无能为力(被我CUT了)。最后ExtClassLoader自已搞定。

5.继序(4)删除C:\Java\jre6\lib\ext\classes目录下的CLASSB

F:\javawork\study\bin>java loader.ClassA
ClassA: sun.misc.Launcher$ExtClassLoader@126b249
Exception in thread "main" java.lang.NoClassDefFoundError: loader/ClassB
        at loader.ClassA.main(ClassA.java:6)

按上面的思路,你一定知道为什么。

6.还原(5)中删除的CLASSB,同时删除CLASSA.

F:\javawork\study\bin>java loader.ClassA
ClassA: sun.misc.Launcher$AppClassLoader@ad3ba4
ClassB: sun.misc.Launcher$ExtClassLoader@126b249

AppClassLoader(默认的系统类加载器)来加载CLASSA,首先委托其父ExtClassLoader去加载,然后AppClassLoader委托bootstrapClassLoader去加载.可两们前辈都无能为力,最后还是落到了AppClassLoader身上,少年英雄很快实现自已的梦想,成功加载CLASSA,然后其CLASSA的加载器(还是AppClassLoader)再去加载CLASSB,喜出望外的是,老爸ExtClassLoader代其完成,大功告成。

7.继序(6)删除C:\Java\jre6\lib\ext\classes目录下的CLASSB

F:\javawork\study\bin>java loader.ClassA
ClassA: sun.misc.Launcher$AppClassLoader@ad3ba4
ClassB: sun.misc.Launcher$AppClassLoader@ad3ba4

同样道理,委托,委托。但这次AppClassLoader在我的破坏下(我删,删),只能自力更生。完成加载。

有一点问题,在测试过程中我的本机并没有CLASSPATH变量:

F:\javawork\study\bin>set classpath
环境变量 classpath 没有定义

但System.out.println(System.getProperty("java.class.path")) 输出:. 即当前目录作为了classpath.

JAVA类加载的委托模型相关推荐

  1. Java类加载器 以及类加载器的委托模型

    我们知道 我们在Java中用到的所有的类都是通过类加载器ClassLoader加载到JVM中的,我们还知道  类加载器 也对应着一个类 ,既然这样那么我们会想 那么ClassLoader类是由谁加载的 ...

  2. Java类加载机制:双亲委托模型

    Java类加载机制:双亲委托模型 前言(废话) 一如既往,这篇博客是我极为浅显的理解,仅仅是我记录我自己成长的一环而已.我以前听我老师说过,什么是进步,进步就是当你三个月后重新再看自己的代码,发现那就 ...

  3. 小明学java基础系列——Java 类加载

    Java类加载学习笔记 一.基本概念 1.1 基本文件类型和概念 1.2 idea程序示例 1.2.1 idea-java源文件 1.2.2 idea-java字节码 1.2.3 idea-类加载 1 ...

  4. JVM之Java类加载器

    前言 通过对Java类加载机制的了解,可以知道大概流程和各自的功能.其中类加载部分的功能是把类的Class文件读入内存,并创建java.lang.Class对象.这部分功能是由类加载器完成的. 1.类 ...

  5. 80070583类不存在_结合JVM源码谈Java类加载器

    一.前言 之前文章 加多:ClassLoader解惑​zhuanlan.zhihu.com 从Java层面讲解了Java类加载器的原理,这里我们结合JVM源码在稍微深入讲解下. 二.Java类加载器的 ...

  6. java类加载器_类加载器

    回顾一下类加载过程 类加载过程:加载->连接->初始化.连接过程又可分为三步:验证->准备->解析. 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的 ...

  7. 36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC

    36.JVM内存分哪几个区,每个区的作用是什么? 37.如和判断一个对象是否存活?(或者GC对象的判定方法) 38.简述java垃圾回收机制? 39.java中垃圾收集的方法有哪些? 40.java类 ...

  8. 深入理解Java类加载器:Java类加载原理解析

    http://blog.csdn.net/zhoudaxia/article/details/35824249 1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpi ...

  9. Java类加载的那些事

    转载自 Java类加载的那些事 前言 Java源代码被编译成class字节码,最终需要加载到虚拟机中才能运行.整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载7个阶段.  加载 1.通过一 ...

最新文章

  1. 关于IT人职业道德的反思(转)
  2. ACwing 245. 你能回答这些问题吗(线段树区间子段最大值+单点修改)
  3. 由LintCode问题子集出发,浅析ArrayList的拷贝问题
  4. 1295 N皇后问题
  5. Linux学习:第三章-Linux常用命令-1
  6. STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出
  7. Unity 导出切片精灵
  8. 人机协作机器人发展趋势_一文了解全球工业机器人发展现状:轻型化、柔性化及人机协作成为发展趋势...
  9. UVA280 LA5588 Vertex【DFS】
  10. Eclipse — 更改包名后导致服务器启动报异常
  11. IT营最新Node.js入门到实战项目视频教程免费下载
  12. linux整站下载工具
  13. oracle的优化器有哪些,Oracle优化器有哪些优化方式?
  14. 最网最全python框架--scrapy(体系学习,爬取全站校花图片),学完显著提高爬虫能力(附源代码),突破各种反爬
  15. 青岛大学计算机科学技术学院辛立强,赵志刚-青岛大学计算机科学技术学院
  16. 计算机主板复位电路的组成,电脑主板复位电路工作原理
  17. 前端面试题之浏览器原理篇
  18. 【CV】Reg2Net:一种用于计算机视觉任务的多尺度骨干架构
  19. 递归算法详解——递归算法的三要素以及例题分析
  20. Notepad++和Vivado中文乱码问题

热门文章

  1. python---之getattr
  2. 什么是冷区热区_墙角装个小柜子 冷区立马变热区 有颜值还实用!
  3. php使用redis消息队列swoole,swoole+Redis实现实时数据推送
  4. 带格式粘贴至html富文本,防止复制/粘贴将网页样式复制到富文本编辑器
  5. 公众号内打开提示404_微信公众号文章内如何插入视频?
  6. opengl光线追踪的程序_【PathTracing】实时光线追踪和BSSRDF的那些事
  7. python sqlserver2008_Python爬取sql server 2008数据
  8. api.cls.php文件,php数据POST提交到API接口
  9. SciPy 非线性方程求解 | Python技能树征题
  10. python 字符串转大写_Python字符串大写()