双亲委派机制

介绍:

Java类加载器采用双亲委派机制,是一种层次化的加载方式。当一个类需要被加载时,首先会交给父类加载器进行加载,如果父类加载器无法找到需要加载的类,则再由当前类加载器进行加载。

类加载过程:

Java类的加载过程主要包括以下三个步骤:

1.加载(Loading):

该阶段是指将编译好的Java类文件加载到JVM中,形成对应的Class对象。在加载阶段,JVM会执行如下操作:

  • 通过类的全限定名获取字节码文件的二进制字节流。
  • 将字节流代表的静态存储结构转化为方法区中的运行时数据结构(如Class对象等)。
  •  在内存区域中生成一个代表该类的Class对象,作为方法区中该类的各种数据访问入口。

2.链接(Linking):

该阶段是指将Java类组装成可执行代码的过程。链接分为以下三个部分:

  • 验证(Verification):该部分是确保所加载的类符合JVM规范。主要包括文件格式、语义基础验证等方面的验证,目的是确保Java类是安全可靠的。如果验证失败,则会抛出相应的异常。
  • 准备(Preparation):该部分是为类的静态成员变量分配内存并设置默认初始值(如0、null等)的过程。这里的静态成员变量包括static修饰的字段和static语句块中的变量。无需考虑变量的赋值操作,仅需要分配内存并设置默认初始值。
  • 解析(Resolution):该部分是指将常量池中的符号引用替换为直接引用的过程。如果在编译阶段无法确定方法或者变量的执行情况,则需要在运行时动态解析。

3.初始化(Initialization):

该阶段是类加载的最后一个阶段,主要目的是为类的静态成员变量赋予正确的初始值,以执行一些静态代码块。Java虚拟机规范规定,只有当程序访问一个类的某个静态属性或者静态方法时,才会触发该类的初始化。

类加载器:

Java类加载器根据其作用范围和加载顺序可以分为以下几种:

1.启动类加载器(Bootstrap ClassLoader):

该类加载器负责加载JRE/lib目录下的核心jar包,如rt.jar等。由于该加载器是由JVM实现的一部分,因此无法在Java程序中直接获取该类加载器对象。

2.扩展类加载器(Extension ClassLoader):

该类加载器负责加载JRE\lib\ext目录下的扩展jar包,比如jmxremote_optional.jar等。

3.应用程序类加载器(Application ClassLoader):

该类加载器也称为系统类加载器,负责加载CLASSPATH环境变量或者classpath参数指定路径中的类,也就是我们通常编写的Java应用程序所依赖的jar包和类文件。

4.自定义类加载器:

除了上述三种类加载器外,在Java中还可以通过编写自定义类加载器来实现特定的类加载规则,从而动态加载类。一般情况下,自定义类加载器都是继承自java.lang.ClassLoader类,重写其中的findClass()方法以实现类的加载。

双亲委派机制:

如果一个类需要被加载器A加载,A会委托给它的父加载器B去加载这个类,如果B找不到,就继续把请求委托给B的父加载器C,直到顶层的启动类加载器。如果顶层的加载器仍然找不到要加载的类,则反馈给下层的加载器,依次向上尝试加载。

双亲委派机制的好处在于:

  1. 避免类的重复加载:由于类加载器会缓存已经加载过的类,所以如果一个类被一个类加载器加载后,其他加载器再次请求加载该类时就可以直接获取缓存中的类,避免类的重复加载,节省内存使用。

  2. 安全性:通过双亲委派机制,可以保证类的加载安全性。当一个类需要加载时,首先会委托父类加载器加载,一般情况下系统类库的加载都是由启动类加载器完成的,因此用户自定义的类不可能覆盖Java的核心类,从而保证了系统的安全性。

  3. 扩展性:通过自定义类加载器,可以在不影响原有类加载流程的前提下,实现自定义的类加载规则,从而扩展Java的类加载能力。

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