类加载器的作用
- 负责将类加载到JVM中
- 审查每个类应该由谁来加载
- 将Class字节码重解析为JVM要求的统一格式
类加载器的加载机制
等级加载机制
某个类加载器加载类时,会首先检查这个类是否已经由自己加载过,如果没有,那么会向上一级父类加载器询问这个类是否应该由上一级的类加载器加载,上一级类加载器根据自己的加载规则判断后将加载结果反馈给下一级,如果也没有进行加载,则询问再上一级类加载器,整个过程指导有一级类加载器能够加载这个类,或者确认这个类不能由自己加载,如果类加载器最终得到上级加载器的确认结果是这个类没有被加载,则当前类加载器会加载这个类。
类加载器类型
JVM平台提供层ClassLoader,这三层ClassLoader可以分为两种类型:
1. Bootstrap ClassLoader,这个类加载器负责加载JVM自身工作需要的类。这个ClassLoader完全由JVM自身控制,别人访问不了这个类,它仅仅是一个类的加载工具,没有父加载器,也没有子加载器。
2. ExtClassLoader,这个类加载器是JVM自身的一部分,但不是JVM亲自实现的,它加载的类既不是JVM内部的类,也和普通的外部类不同,它加载的类都位于System.getProperty(“java.ext.dirs”)目录下。这个类加载器也没有父类。
3. AppClassLoader,这个类加载器加载普通类,它的父类是ExtClassLoader,所有在System.getProperty(“java.class.path”)目录下的类都可以被这个类加载器加载。
4. 应用自己实现的类加载器,无论直接实现抽象类ClassLoader,还是继承URLClassLoader类,它的父加载器都是AppClassLoader,自己实现的类加载器最终都要调用ClassLoader.getSystemClassLoader()方法,这个方法返回的就是AppClassLoader。
ExtClassLoader和AppClassLoader都位于sun.misc.Launcher类中,是它的内部类。它们都继承自URLClassLoader。
类加载器加载类的过程
JVM加载class文件到内存有两种方式:
* 隐式加载,不通过在代码里调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存中。
* 显示加载,代码中显式调用ClassLoader类来加载。
加载过程如下:
加载过程
链接过程
加载字节码到内存,这个过程需要findClass方法来实现。对于URLClassLoader来说,其构造方法中包含一个URL[]数组,用于指定类文件所在的位置,它会被初始化为URLClassPath类用于后面查找类文件。
设置ClassLoader的搜索路径
ClassLoader类型 | 参数选项 | 说明 |
---|---|---|
Bootstrap ClassLoader | -Xbootclasspath: | 设置Bootstrap ClassLoader的搜索路径 |
ExtClassLoader | -Djava.ext.dirs | 设置Ext ClassLoader的搜索路径 |
AppClassLoader | -Djava.class.path或者-cp或者-classpath | 设置AppClassLoader的类搜索路径 |
ClassLoader类
介绍
各种类加载器的抽象父类,一般我们实现自己的类加载器时通常继承它的子类URLClassLoader,这个子类实现了大部分抽象方法。
它的方法
- Class