Java虚拟机中ClassLoader的机制分析

首先我们得明白什么是类加载器(ClassLoader):

A【类加载的作用】:java中的类加载器就是把java字节码(class文件)从硬盘中加载到内存中,然后做一些处理,这就是类加载器。

一般来说,类加载器本身是一个java类,但是BootStrap加载器是C++写成的。是所有加载器的根。

默认情况下,java提供了三个默认加载器:

  • BootStrap:只从classpath指定的目录或者jar包下面加载类
  • ExtClassLoader:加载JRE/lib/ext/*.jar
  • AppClassLoader:专门加载JRE/lib/rt.jar

先看一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package zju.zsq.day01;
public class ClassLoaderTest {
public static void main(String[] args) {
System.out.println(
ClassLoaderTest.class.getClassLoader()
.getClass().getName());
System.out.println(
System.class.getClassLoader()
);
ClassLoader loader = ClassLoaderTest.class.getClassLoader();
//看下树状结构,如果为null就代表找不到java的class文件,等于找到了bootstrap(C++实现的加载)
while(loader != null){
System.out.println(loader.getClass().getName());
loader = loader.getParent();
}
System.out.println(loader);
/**
* AppClassLoader:只从classpath指定的目录或者jar包下面加载类
* ExtClassLoader:JRE/lib/ext/*.jar
* BootStrap:专门加载JRE/lib/rt.jar
*/
System.out.println(new ClassLoaderAttachment().toString());
}
}

输出结果为:

1
2
3
4
5
sun.misc.Launcher$AppClassLoader
null
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
null

从代码里面我们可以看到,从上到下加载器是成树状的(其中null为BootStrap,因为上诉代码得到的是classname,但是C++没有生产字节码,所以为null),再让我们看看下图:

java虚拟机加载一个类的时候,到底派出哪个类加载器去加载呢?

A :一般来说是当前线程的类加载器去加载线程中的第一个类,Thread.currentThread().getContextClassLoader(),当然从上面的代码我可以知道加载ClassLoaderTest这个类是AppClassLoader加载器。具体来说,ClassLoaderTest用这个AppClassLoader加载器来加载,但是它不是立即就加载的 。过程如下:

  • 1.ClassLoaderTest先找到他的加载器AppClassLoader
  • 2.AppClassLoader就委托到父加载器ExtClassLoader加载
  • 3.ExtClassLoader开始加载,找不到加载类,就开始委托给它的子加载器ExtClassLoader
  • 4.ExtClassLoader开始加载,找不到加载类,就开始委托给它的子加载器AppClassLoader
  • 5.AppClassLoader开始加载,找到加载,加载完毕。

这是一个委托机制,一般来说,先是从现在类的加载器,一层层委托到最顶层的加载器,然后顶层的加载器,开始加载,找不到加载类,就委托给下一层,如果在到当前类的加载器之前加载完毕,就结束。如果直到当前类还加载不了,就抛ClassNotFoundException。

这个委托机制的优点是:方便集权管理,比如说只有不会生成多份字节码。

在这里突然就想到了一份经典的面试题,能否自己重写Java.lang.system这个类
答案是当然可以,但是一般情况下写了也得于白写,当委托到最顶上的那个加载器就直接被加载了。除非自己写一个加载器,然后还要抛开委托机制

好了,今天算是把加载器粗略的了解下,与诸君共勉!加油!