classloader整理

classloader它就是用来加载Class文件到JVM,以供程序使用的。我们知道,java程序可以动态加载类定义,而这个动态加载的机制就是通过ClassLoader来实现的.
所有的classloader都是java写的,除了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被加载-->load位于sun.misc.Launcher中的ExtClassLoader,设置它的parent为null-->load位于sun.misc.Launcher中的AppClassLoader,设置parent为ExtClassLoader-->AppClassLoader载入我们自己的class,但是在AppClassLoader无法载入的时候,它们也有可能被ExtclassLoader或者bootstrap loader载入

我们自定义的ClassLoader都必须继承ClassLoader这个抽象类,而每个ClassLoader都会有一个parent ClassLoader,我们可以看一下ClassLoader这个抽象类中有一个getParent()方法,这个方法用来返回当前ClassLoader的parent。这里之所以这样做,就是所谓的双亲委托模式。当使用一个自定义的classloader加载一个类,classloader会让它的parent classloader去加载,如果parent加载不成功,再拿过来自己加载。如下就是源码:
 protected synchronized Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
// First, check if the class has already been loaded
Class c = findLoadedClass(name);
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);
} else {
c = findBootstrapClass0(name);
}
} catch (ClassNotFoundException e) {
// If still not found, then invoke findClass in order
// to find the class.
c = findClass(name);
}
}
if (resolve) {
resolveClass(c);
}
return c;
}



classloader中的一些重要的方法
1)loadClass
ClassLoader.loadClass() 是ClassLoader的入口点。该方法的定义为:Class loadClass( String name, boolean resolve );
name:JVM 需要的类的名称,如 Foo 或 java.lang.Object。
resolve:参数告诉方法是否需要解析类。

2)defineClass
defineClass方法接受由原始字节组成的数组并把它转换成Class对象。

3)findSystemClass
findSystemClass方法从本地文件系统中寻找类文件,如果存在,就使用defineClass将原始字节转换成Class对象,以将该文件转换成类。

4)resolveClass
可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的loadClass时可以调用resolveClass,这取决于loadClass的resolve参数的值。

5)findLoadedClass
findLoadedClass充当一个缓存:当请求loadClass装入类时,它调用该方法来查看ClassLoader是否已装入这个类,这样可以避免重新装入已存在类所造成的麻烦。

一些常见的疑问
1.自定义的ClassLoader,它的parent是AppClassLoader。与它被谁加载的并没有关系。
2.ExtClassLoader和AppClassLoader都是URLClassLoader的子类.AppClassLoader的URL是由系统参数java.class.path取出的字符串决定,而java.class.path由 运行java.exe时 的-cp或-classpath或CLASSPATH环境变量决定。ExtClassLoader查找的url是系统变量java.ext.dirs默认为jdk\jre\lib\ext。Bootstrap loader的查找url是-Xbootclasspath所指定的路径。在程序运行后System.setProperty()来改变系统变量并不能改变以上加载的路径,因为classloader读取在System.setProperty之前,而且sun.boot.class.path是在程序中写死的,完全不能改变。
3.NoClassDefFoundError:当java源文件已编译成.class文件,但是ClassLoader在运行期间在其搜寻路径load某个类时,没有找到.class文件就会报这个错。ClassNotFoundException:试图通过一个String变量来创建一个Class类时不成功则抛出这个异常。

一般应用场景
1.程序运行中加载特别url或自定义的位置的class文件.
2.动态reload class文件.
3.用来加载加密了的class文件,比如用RC4方式加密的class文件,先解密再加载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值