getClassLoader():取得当前类的加载器ClassName.class.getClassLoader()(以下内容为转载他人)
JVM启动,会形成3个类加载器组成的初始化加载器层次结构:
bootstap classloader (加载核心类)
||
extension classloader(加载ext(目录),即java.ext.dirs())
||
system classloader (加载-classpath或者java.class.path或者CLASSPATH)
ClassLoader机制:
a)全盘负责:一个classloader加载一个class后,这个class所引用或者依赖的类也由这个classloader载入,除非显示的用另一个classloader载入
b)委托机制:先由父加载器加载,除非父加载器找不到时才从自己的类路径中去寻找
c)Cache机制:classloader采用缓存机制,即先查cache;若cache中保存了这个class就直接返回;若无,才从文件读取和转化为class并放入cache
ClassLoader加载类顺序:
1)检查cache是否有该类:
11)若有直接返回
12)若无,请求父类加载
121) 若无父,则从bootstap classloader加载
2)加载:
21)寻找class文件(丛与此classloader相关的类路径中寻找)
22)从文件载入class
23)找不到则抛出ClassNotFoundeException
3)扩展:
记载时即2),覆写findClass可以实现自己的载入策略
记载时即2),覆写loadClass来实现自己的载入过程
如何实现运行时动态载入与更新
本质:只要动态改类搜索路径和清除classloader的cache已载入的class就ok
做法:
1)继承ClassLoader:覆写loadClass方法,动态寻找class文件
2)只要重新使用一个新的类搜索路径来new一个classloader就可以,这样既更新了类的搜索路径以便来载入新的class,也更新生成了一个空白的cache
classloader载入的方式
1)Pre-loading 预先载入,载入基础类
2)load-on-demand 按需求载入
JDK为啥有两个JRE?
JDK中jre是运行java本身的程序,如javac
ProgramFile(默认安装)中jre是运行用户编写的java程序
classloader有啥妙用(1)?
这个问题得从自定义的classloader身上说,那自定义classloader缘由是什么呢?
告诉你:大多是因为编译时无法预知运行时需要哪些类,特别是app server;因此自定义classloader,运行时指定路径,来加载这个路径下的class
特殊说明
特殊说明1:如果没有特殊指定,用户自定义的classloader都把system classloader作为它的父加载器
特殊说明2:jvm认为不同的classloade载入相同名字的class是不同的,即使从同一个class文件载入
classloader有啥妙用(2)?
看到特殊说明2,你或许就会感觉疑惑或者不爽;啥概念?
以servlet、ejb等容器来剖析这个问题:
将接口或者基类放入classpath <---------system classloader
执行时,动态载入实现或者继承这些接口或者基类的子类;<---------customized classloader
||
||
用customized classloader载入类时,发现它有一个父类class(extends);
但是在载入它时,jvm先加载父类class; 这个父类是system classloader能识别的; 根据“委托机制”它将由system classloader来加载;
然后customized classloader(实际是system classloader来加载)再载入这个class,创建一个实例,转型为父类;
jvm就使用system classloader再次载入父类class,然后将此实例转型为这个父类class;
这个过程加载了两个父类class,都是由system classloader载入;即同一个classloader载入同一个文件,造型不会由异常
web app server大概是这样工作的;这样载入了任何继承了servlet的class并正确运行它们,不管class是什么,都它们实例化为一个servlet class
posted on 2008-12-23 14:46
FINDER 阅读(458)
评论(0) 编辑 收藏 所属分类:
J2SE