当前位置: 技术文章>> 100道Java面试题之-Java中的类加载器层次结构是怎样的?双亲委派模型是什么?
文章标题:100道Java面试题之-Java中的类加载器层次结构是怎样的?双亲委派模型是什么?
### Java中的类加载器层次结构
Java中的类加载器层次结构主要包括以下几种类加载器,它们之间存在一定的父子关系,这种关系主要基于双亲委派模型:
1. **引导类加载器(Bootstrap ClassLoader)**:
- 这是最顶层的类加载器,由C++编写实现,不继承自`java.lang.ClassLoader`。
- 它主要负责加载Java的核心库,这些库通常位于`JAVA_HOME/jre/lib/rt.jar`(或对应JDK版本的路径)中,以及其他由JVM指定的路径。
- 由于是原生代码实现,因此在Java中无法直接获取到它的实例。
2. **扩展类加载器(Extension ClassLoader)**:
- 由Java编写,继承自`java.lang.ClassLoader`。
- 主要负责加载Java的扩展库,这些库位于`JAVA_HOME/jre/lib/ext`(或`java.ext.dirs`系统属性指定的路径)中。
- 它被引导类加载器所加载。
3. **系统类加载器(System ClassLoader)或应用程序类加载器(Application ClassLoader)**:
- 同样由Java编写,继承自`java.lang.ClassLoader`。
- 它负责加载用户类路径(classpath)上所指定的类库,包括开发者自己编写的Java类。
- 它被扩展类加载器所加载。
4. **自定义类加载器**:
- 开发人员可以通过继承`java.lang.ClassLoader`类来实现自己的类加载器,以满足特定的需求。
- 自定义类加载器可以加载指定路径下的类,或者通过特殊的方式加载类,比如从网络加载。
### 双亲委派模型
双亲委派模型是Java类加载器在加载类时采用的一种机制,它确保了类的加载过程具有安全性和一致性。具体来说,当某个类加载器需要加载一个类时,它会首先尝试将这个任务委派给它的父类加载器去完成,依次递归,直到引导类加载器。只有当父类加载器无法完成这个加载任务时,子类加载器才会尝试自己去加载。
双亲委派模型的主要优点包括:
1. **避免重复加载**:由于每个类只会被加载一次,避免了重复加载相同的类,从而提高了程序执行效率。
2. **保证安全性**:通过优先委派给父加载器进行加载,可以避免恶意代码通过自定义的类加载器来劫持JVM,从而保证了程序的安全性。
3. **统一管理**:由于所有的类的加载都由顶层的启动类加载器加载,因此可以统一管理类的加载,从而更好地进行内存管理和JVM优化。
**工作流程**:
1. 当一个类加载器接收到一个类加载请求时,它首先检查自己是否已经加载过这个类。
2. 如果没有加载过,它会将这个请求委派给它的父类加载器。
3. 父类加载器同样会先检查自己是否已经加载过这个类,如果没有,则继续向上委派,直到引导类加载器。
4. 如果引导类加载器也无法加载这个类,那么类加载请求会依次向下传递,直到某个子类加载器能够加载这个类为止。
5. 如果所有的类加载器都无法加载这个类,则抛出`ClassNotFoundException`。
这种机制确保了Java核心库的类型安全,避免了用户自定义的类与Java核心库中的类发生冲突。