在Java虚拟机(JVM)中,类加载器(ClassLoader)是负责动态加载类到JVM中的关键组件。类加载器的工作是在运行时查找和导入二进制格式的类文件,并将这些文件中的类信息转换成方法区内的运行时数据结构。类加载器的使用保证了JVM能够在不依赖于特定文件系统的前提下运行Java应用程序。
JVM默认提供的类加载器层次结构如下:
-
Bootstrap ClassLoader(引导类加载器)
- 这是最基础的类加载器,由C++实现,没有对应的Java对象。
- 它负责加载JDK核心类库,如
rt.jar
、charsets.jar
等,这些类是可信的,不需要验证。 - Bootstrap ClassLoader无法被Java代码直接引用。
-
Extension ClassLoader(扩展类加载器)
- 负责加载标准扩展目录(例如,
<JAVA_HOME>/lib/ext
或通过java.ext.dirs
系统属性指定的目录)下的JAR包或者类文件。
- 负责加载标准扩展目录(例如,
-
Application ClassLoader(系统/应用类加载器)
- 也称为System ClassLoader,它是用户自定义类加载器的父加载器。
- 负责加载CLASSPATH环境变量或
-cp
、-classpath
命令行选项指定的类路径下的类和jar包。
-
自定义类加载器(User-Defined ClassLoaders)
- 开发者可以根据需要创建自己的类加载器,用于从非标准位置加载类,比如网络、数据库或其他特殊存储介质。
- 自定义类加载器通常会继承自
java.lang.ClassLoader
并重写其加载方法。
类加载器的核心机制——双亲委派模型:
- 当一个类加载器收到加载类的请求时,它首先不会自己去尝试加载这个类,而是把这个请求委托给它的父加载器去完成。
- 如果父加载器还存在其父加载器,则继续向上委托,直到顶层的Bootstrap ClassLoader。
- 只有当父加载器无法找到要加载的类时,当前加载器才会尝试自己去加载该类。
- 这种机制确保了类的唯一性,避免了重复加载和安全性问题,同时也支持了类隔离和SPI服务提供者的插件化机制。
在实战场景中,对类加载器的深入理解和灵活运用对于解决诸如热部署、模块化、安全隔离等问题具有重要意义。