JAVA类加载的委托模型
关于JAVA的类加载器,网上有很多这方面资料,这里只做测试,不多累述。JVM有三个内置加载器: bootstrapClassLoader(由C语言编写,固化在jvm上)、ExtClassLoader、AppClassLoader。三个加载器从上到下呈父子关系,形成了“类加载委托模型”:即儿子的事情,父亲能做的,他一定会代劳(以免累到儿子),父亲的事情,一定会自已做,即使自已无法完成,也不会劳及儿子。三个类的加载路径分别为(更多细节参考google):
BootstrapClassLoader: sun.boot.class.path
ExtClassLoader: java.ext.dirs AppClassLoader: java.class.path
首先定义两个类:
- package loader;
- public class ClassA {
- public static void main(String args[]){
- System.out.println("ClassA: " + ClassA.class.getClassLoader());
- ClassB a = new ClassB();
- System.out.println("ClassB: " + ClassA.class.getClassLoader());
- }
- }
- //
- package loader;
- public class ClassB {
- }
拷贝三份到: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类加载的委托模型相关推荐
- Java类加载器 以及类加载器的委托模型
我们知道 我们在Java中用到的所有的类都是通过类加载器ClassLoader加载到JVM中的,我们还知道 类加载器 也对应着一个类 ,既然这样那么我们会想 那么ClassLoader类是由谁加载的 ...
- Java类加载机制:双亲委托模型
Java类加载机制:双亲委托模型 前言(废话) 一如既往,这篇博客是我极为浅显的理解,仅仅是我记录我自己成长的一环而已.我以前听我老师说过,什么是进步,进步就是当你三个月后重新再看自己的代码,发现那就 ...
- 小明学java基础系列——Java 类加载
Java类加载学习笔记 一.基本概念 1.1 基本文件类型和概念 1.2 idea程序示例 1.2.1 idea-java源文件 1.2.2 idea-java字节码 1.2.3 idea-类加载 1 ...
- JVM之Java类加载器
前言 通过对Java类加载机制的了解,可以知道大概流程和各自的功能.其中类加载部分的功能是把类的Class文件读入内存,并创建java.lang.Class对象.这部分功能是由类加载器完成的. 1.类 ...
- 80070583类不存在_结合JVM源码谈Java类加载器
一.前言 之前文章 加多:ClassLoader解惑zhuanlan.zhihu.com 从Java层面讲解了Java类加载器的原理,这里我们结合JVM源码在稍微深入讲解下. 二.Java类加载器的 ...
- java类加载器_类加载器
回顾一下类加载过程 类加载过程:加载->连接->初始化.连接过程又可分为三步:验证->准备->解析. 一个非数组类的加载阶段(加载阶段获取类的二进制字节流的动作)是可控性最强的 ...
- 36.JVM内存分哪几个区,每个区的作用是什么、如和判断一个对象是否存活、java垃圾回收机制、垃圾收集的方法有哪些、java类加载过程、类加载机制、双亲委派、Minor GC和Major GC
36.JVM内存分哪几个区,每个区的作用是什么? 37.如和判断一个对象是否存活?(或者GC对象的判定方法) 38.简述java垃圾回收机制? 39.java中垃圾收集的方法有哪些? 40.java类 ...
- 深入理解Java类加载器:Java类加载原理解析
http://blog.csdn.net/zhoudaxia/article/details/35824249 1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpi ...
- Java类加载的那些事
转载自 Java类加载的那些事 前言 Java源代码被编译成class字节码,最终需要加载到虚拟机中才能运行.整个生命周期包括:加载.验证.准备.解析.初始化.使用和卸载7个阶段. 加载 1.通过一 ...
最新文章
- 关于IT人职业道德的反思(转)
- ACwing 245. 你能回答这些问题吗(线段树区间子段最大值+单点修改)
- 由LintCode问题子集出发,浅析ArrayList的拷贝问题
- 1295 N皇后问题
- Linux学习:第三章-Linux常用命令-1
- STM32学习及开发笔记八:采用主从计时器实现精确脉冲输出
- Unity 导出切片精灵
- 人机协作机器人发展趋势_一文了解全球工业机器人发展现状:轻型化、柔性化及人机协作成为发展趋势...
- UVA280 LA5588 Vertex【DFS】
- Eclipse — 更改包名后导致服务器启动报异常
- IT营最新Node.js入门到实战项目视频教程免费下载
- linux整站下载工具
- oracle的优化器有哪些,Oracle优化器有哪些优化方式?
- 最网最全python框架--scrapy(体系学习,爬取全站校花图片),学完显著提高爬虫能力(附源代码),突破各种反爬
- 青岛大学计算机科学技术学院辛立强,赵志刚-青岛大学计算机科学技术学院
- 计算机主板复位电路的组成,电脑主板复位电路工作原理
- 前端面试题之浏览器原理篇
- 【CV】Reg2Net:一种用于计算机视觉任务的多尺度骨干架构
- 递归算法详解——递归算法的三要素以及例题分析
- Notepad++和Vivado中文乱码问题
热门文章
- python---之getattr
- 什么是冷区热区_墙角装个小柜子 冷区立马变热区 有颜值还实用!
- php使用redis消息队列swoole,swoole+Redis实现实时数据推送
- 带格式粘贴至html富文本,防止复制/粘贴将网页样式复制到富文本编辑器
- 公众号内打开提示404_微信公众号文章内如何插入视频?
- opengl光线追踪的程序_【PathTracing】实时光线追踪和BSSRDF的那些事
- python sqlserver2008_Python爬取sql server 2008数据
- api.cls.php文件,php数据POST提交到API接口
- SciPy 非线性方程求解 | Python技能树征题
- python 字符串转大写_Python字符串大写()