Java中的双亲委派机制

2024-04-30 14:29:58 浏览数 (1)

每天早上七点三十,准时推送干货

前两天我们刚刚说了栈帧和动态链接,也就是 JVM 虚拟机中的一部分,今天我们来聊聊这个 类加载器,他也是 JVM 中的一部分。

类加载器

Java的类加载器(Class Loader)是Java虚拟机(JVM)的一部分,它负责将编译后的Java字节码加载到JVM中并解析为可执行的Java类。类加载器在Java中扮演着至关重要的角色,它提供了动态加载类的能力,使得Java应用程序可以在运行时加载和使用编译时不存在的类。

Java的类加载器基于三个核心原则工作:委托、可见性和唯一性。委托原则指的是,当一个类加载器收到加载类的请求时,它会首先将这个请求转发给父类加载器进行加载。只有当父类加载器无法找到或无法加载该类时,子类加载器才会尝试自行加载。这种机制有助于保证类的加载顺序和一致性。

可见性原则允许子类加载器查看由父类加载器加载的所有类,但父类加载器不能查看由子类加载器加载的类。这确保了类加载器之间的层次结构,并允许子类加载器扩展或覆盖父类加载器加载的类。

唯一性原则则保证一个类文件只被加载一次。这是通过委托原则实现的,确保子类加载器不重新加载父类加载器已经加载过的类。这有助于避免类加载的重复和资源浪费。

Java中主要有以下几种类型的类加载器:

  • 1.启动类加载器(Bootstrap Class Loader):这是JVM的一部分,负责加载Java核心类库,如rt.jar中的类。由于引导类加载器涉及到JVM的核心实现,所以一般情况下,应用程序开发人员并不需要直接与之交互。
  • 2.扩展类加载器(Extension Class Loader):这个加载器用于加载Java的扩展类库,这些类库通常位于JRE的lib/ext目录下。扩展类加载器是由Java编写的,并由启动类加载器加载。
  • 3.应用程序类加载器(Application Class Loader):也称为系统类加载器,是加载应用程序类的默认类加载器。它负责加载应用程序classpath下的类,包括用户自定义的类和第三方库。这是Java中最常用的类加载器。

他们具体的功能要点其实差距不大都是那么几样:

类加载器的主要功能

加载位置:扩展类加载器主要负责加载位于<JAVA_HOME>/lib/ext目录或系统变量-Djava.ext.dirs指定位置中的类库。这些类库通常包含Java的扩展功能或第三方库,用于扩展Java的核心功能。

委托机制:扩展类加载器在接收到加载请求时,首先会将其委派给父类加载器(通常是启动类加载器)进行加载。只有当父类加载器无法加载该类时,扩展类加载器才会尝试自行加载。这种委托机制确保了类的加载顺序和一致性,避免了类的重复加载。

安全性:通过委托机制,扩展类加载器确保了加载的类库符合JVM的规范,并且没有安全方面的问题。父类加载器会先对类库进行验证,确保其完整性和安全性,然后再由扩展类加载器进行加载。

灵活性:虽然扩展类加载器主要负责加载特定的扩展类库,但Java也允许开发者通过继承java.lang.ClassLoader类来创建自定义的类加载器,以实现更复杂的类加载策略。这种灵活性使得Java能够适应不同的应用场景和需求。

这时候,我们就提到了委派机制,那我们就得来看看这个双亲委派机制是什么了?

双亲委派机制

双亲委派机制(Parent Delegation Mechanism)是Java中类加载器(ClassLoader)的一种工作机制,旨在保证类的加载是有序的,避免重复加载同一个类,并确保类的安全性和一致性。

在Java中,类加载器负责加载类的字节码并创建对应的Class对象。当一个类加载器收到类加载请求时,它会先将该请求委派给它的父类加载器去尝试加载。只有当父类加载器无法加载该类时,子类加载器才会尝试加载。这种机制的设计目的是保证类的加载顺序和依赖关系,从而确保Java程序的稳定性。

Java中的类加载器形成了一个层次结构,根加载器(Bootstrap ClassLoader)位于最顶层,它负责加载Java核心类库。通过双亲委派机制,可以确保类在被加载时,先从上层的加载器开始查找,逐级向下,直到找到所需的类或者无法找到为止。这种机制的好处是可以避免类的重复加载,提高了类加载的效率和安全性。

双亲委派机制的作用主要体现在以下几个方面:

提高类加载的安全性:通过确保类的加载是从上往下进行的,可以防止恶意的类替换或者篡改已经存在的类。父类加载器优先加载,可以保护核心Java类库不被恶意代码替换或篡改。

提高类加载的效率:避免了重复加载已经存在的类。当一个类被加载后,它就会保存在内存中,下次再加载该类时,就直接从内存中获取,避免了重复加载的时间和空间消耗。

简化类加载器的实现:双亲委派机制将不同类加载器的职责划分明确,每个类加载器只需要关注自己的加载范围,不需要关注其他类加载器的加载过程,从而简化了类加载器的实现和维护。

需要注意的是,虽然双亲委派机制在大多数情况下是有益的,但在某些特殊的应用场景下,可能需要打破这种机制以实现自定义的类加载策略。例如,在模块化编程或动态代码生成等场景中,可能需要自定义类加载器并重写其加载类的逻辑。

总的来说,双亲委派机制是Java类加载器的重要工作机制之一,它确保了类的有序加载、提高了加载效率和安全性,并简化了类加载器的实现。同时,它也为Java应用程序提供了更灵活和安全的类加载机制。

所以双亲委派机制在 JVM 中是十分重要的,如果没有双亲委派机制则会出现下面的这几种情况了:

1.安全性降低

Java的核心类库会被随意替换或篡改

2.类加载冲突

不同的类加载器可能会加载同一个类的不同版本,这会导致类加载冲突

3.类的加载顺序将变得不可预测

4.破坏JVM的模块化

所以,你对双亲委派机制了解了么?面试知道该怎么描述了吧


0 人点赞