jvm之类加载双亲委托机制

岁岁金河复玉关,不辞镜里望崔山。——唐代杜甫《春望》

双亲委托机制

双亲委托机制是指在类加载器加载类时,如果一个类加载器收到了加载请求,它首先将请求委托给父类加载器,如果父类加载器仍无法找到所需的类,则再由当前类加载器自己加载。

具体来说,当一个类加载器需要加载一个类时,它首先会判断该类是否已经被加载过。如果已经被加载过,则直接返回该类的 Class 对象。如果没有被加载过,则该类加载器会将加载请求委托给其父类加载器,让父类加载器去尝试加载。如果父类加载器无法加载该类,那么再由当前类加载器自己去加载。

这种委托机制是为了保证类的唯一性和安全性。在双亲委托机制下,同一个类在不同的类加载器中只会被加载一次,避免了类的重复加载和冲突。同时,由于父类加载器会优先加载类,所以可以保证程序使用的是系统中已经存在的类,防止恶意程序通过自定义类加载器加载恶意类。

在 Java 中,有三种类加载器:引导类加载器(Bootstrap ClassLoader)、扩展类加载器(Extension ClassLoader)和应用程序类加载器(Application ClassLoader)。其中,引导类加载器是 Java 虚拟机自带的类加载器,它负责加载系统类库,如 rt.jar,它是所有类加载器的根加载器。扩展类加载器负责加载 Java 的扩展类库,如 $JAVA_HOME/lib/ext 目录下的 jar 包。应用程序类加载器负责加载应用程序的类,它通常是用户自定义的类加载器。

在双亲委托机制中,引导类加载器没有父类加载器,扩展类加载器的父类加载器是引导类加载器,应用程序类加载器的父类加载器是扩展类加载器。如果某个类加载器需要加载的类无法在父类加载器中找到,它就会尝试自己加载,这样就保证了类的唯一性和安全性。

总之,双亲委托机制是 Java 类加载器的一种重要机制,它通过将类加载请求委托给父类加载器,保证了类的唯一性和安全性。

双亲委托机制有什么好处

双亲委托机制有以下几个好处:

  1. 避免类的重复加载:双亲委托机制可以避免同一个类被多个类加载器重复加载,从而保证类的唯一性。

  2. 防止恶意代码:由于所有类都是通过父类加载器向上委托加载的,因此可以防止恶意代码通过自定义类加载器加载恶意类。

  3. 保证类的安全性:通过将类加载请求委托给父类加载器,可以保证系统中使用的都是已经存在于 Java 系统中的类,防止程序使用不安全的类。

  4. 提高系统性能:双亲委托机制可以有效地避免类的重复加载,从而减少了系统内存的占用和类的加载时间,提高了系统性能。

  5. 提高代码的复用性:由于同一个类只会被加载一次,可以提高代码的复用性,减少代码冗余。

总之,双亲委托机制是 Java 类加载器的一种重要机制,它可以有效地保证类的唯一性和安全性,提高系统性能和代码复用性,是 Java 语言的一个重要特性。

一个双亲委托的具体例子

一个常见的例子是对于 Java 标准库中的类的加载。当我们在 Java 程序中使用一些标准库中的类时,如 java.lang.String,它是由引导类加载器进行加载的。当我们使用自己编写的类时,如 com.example.MyClass,它则是由应用程序类加载器进行加载的。

加载我的类具体过程

双亲委派模型(Parent Delegation Model)是Java类加载器在加载类时所遵循的一种策略。其主要思想是:如果一个类加载器收到了类加载请求,它首先不会自己去加载这个类,而是把请求委派给父类加载器去完成。每一个层次的类加载器都会遵循这个原则,直到最顶层的启动类加载器(Bootstrap ClassLoader)。如果顶层类加载器无法加载该类,那么请求会沿着层次结构向下传递,直到找到一个能够加载该类的类加载器或者无法加载该类为止。

在加载 com.example.MyClass 类时,双亲委派模型的具体过程如下:

首先,应用程序类加载器(Application ClassLoader)接收到加载 com.example.MyClass 的请求。
应用程序类加载器将加载请求委托给它的父类加载器,即扩展类加载器(Extension ClassLoader)。
3. 扩展类加载器继续将加载请求委托给它的父类加载器,即启动类加载器(Bootstrap ClassLoader)。

启动类加载器在JDK的核心类库(如:rt.jar)中查找 com.example.MyClass。如果找到了这个类,就加载并返回给扩展类加载器;如果没有找到,启动类加载器会返回一个加载失败的信号。
扩展类加载器接收到启动类加载器的加载失败信号后,会在扩展类库(如:jre/lib/ext目录中的jar文件)中查找 com.example.MyClass。如果找到了这个类,就加载并返回给应用程序类加载器;如果没有找到,扩展类加载器会返回一个加载失败的信号。
应用程序类加载器接收到扩展类加载器的加载失败信号后,会在自己负责的类路径(如:CLASSPATH环境变量中指定的路径、应用程序的lib目录等)中查找 com.example.MyClass。如果找到了这个类,就加载并返回;如果没有找到,应用程序类加载器会抛出一个 ClassNotFoundException。

在整个加载过程中,双亲委派模型确保了类的唯一性和安全性。这种模型避免了同一个类被多个类加载器重复加载,同时也保证了核心Java类库不会被篡改或覆盖

双亲委托机制在加载 String类的具体过程

String 类是Java核心类库的一部分,位于 java.lang 包中。在加载 String 类时,双亲委派模型的具体过程如下:

首先,应用程序类加载器(Application ClassLoader)接收到加载 java.lang.String 的请求。
应用程序类加载器将加载请求委托给它的父类加载器,即扩展类加载器(Extension ClassLoader)。
扩展类加载器继续将加载请求委托给它的父类加载器,即启动类加载器(Bootstrap ClassLoader)。
启动类加载器在JDK的核心类库(如:rt.jar)中查找 java.lang.String。由于 String 类是核心类库的一部分,启动类加载器会找到这个类,然后加载并返回给扩展类加载器。
扩展类加载器接收到启动类加载器加载并返回的 java.lang.String类,将其传递给应用程序类加载器。最后,应用程序类加载器接收到已加载的java.lang.String` 类,并将其提供给应用程序使用。

在整个加载过程中,双亲委派模型确保了类的唯一性和安全性。这种模型避免了同一个类被多个类加载器重复加载,同时也保证了核心Java类库不会被篡改或覆盖。


总之,类的加载过程是一个由下至上、由内而外的过程,即由类加载器的子节点向父节点逐级加载,并且在加载过程中,双亲委托机制会保证同一个类在同一个类加载器实例中只会被加载一次,从而保证类的唯一性和安全性。

因此,双亲委托机制可以保证 Java 中所有的类都是由类加载器层次结构中的较高层次的类加载器进行加载的,从而保证类的唯一性和安全性。

你可能感兴趣的:(JVM,jvm,java,开发语言)