是什么
我们知道,当我们使用一个类时需要使用全限定名将它导入,而执行这个行为的就是类加载器。本文就将类导入虚拟机内存这个行为上进行展开。
简单的讲,这就是将class文件导入进虚拟机内存提供服务。而类加载器的选择决定你是否能导入正确的类。
常见的类加载器
- 引导类加载器:由原生语言实现,负责加载加载核心类库(%JRE_HOME%\lib下的rt.jar、resources.jar、charsets.jar和class等。另外需要注意的是可以通过启动jvm时指定-Xbootclasspath和路径来改变Bootstrap ClassLoader的加载目录。比如java-Xbootclasspath/a:path被指定的文件追加到默认的bootstrap路径中。),位于虚拟机内部。
- 继承ClassLoader的加载器,位于虚拟机外面,一般有:
- 扩展加载器,负责加载java扩展类库,jre/lib/ext里面的文件。
- 系统加载器,负责加载应用类文件,由CLASSPATH环境变量设置的类路径或者jar/zip文件里的类。
- 插件加载器:有的应用为插件架构,可以使用URLClassLoader实例加载插件。
- 自定义加载器:可以通过继承ClassLoader,覆盖findclass()来实现自己特殊目的的加载器,但需要注意loadClass()的代理顺序(双亲委派)
需要注意的地方
- 类的唯一性是有全限定名和类加载器共同确定,不同加载器加载的类是不一样的。根据这个特性还可以将类加载器作为命名空间。
- 类加载器的使用顺序。首先,每个类加载器都有一个父加载器(引导加载器除外),优先使用父加载器,只有当父加载器处理失败时才会使用子加载器,这就是双亲委派模型。根据继承关系,类加载器的调用构成一颗单向树:
插件加载器 -> 系统加载器 -> 扩展加载器 -> 引导加载器(树根)
一般情况下是透明的,但是当你需要导入插件类,但当前为系统加载器,则会找不到该类,而出现类加载器倒置现象。因此,在适当的地方使用正确的加载器十分重要。 - 类加载器关键就是路径,不同的类加载器其对应的路径是不同的。需要哪的类就用什么类加载器。
- 类加载器原理解读,有一篇大神的博客 一看你就懂,超详细java中的ClassLoader详解
- 类加载器会缓存已经加载的类。
- 推荐大神文章全面理解类加载器
引用文档
--《java核心技术卷二-第9章安全》
-- 一看你就懂,超详细java中的ClassLoader详解