Java类加载过程与双亲委派机制

 一、JVM体系

  • Java程序运行在虚拟机上,编译器对.java文件进行javac编译成为.class文件,之后.class文件在JVM进行类加载与执行。

Java类加载过程与双亲委派机制_第1张图片

  • 由上图所示,JVM一共有三个子系统,类加载子系统、运行时数据区、执行引擎。但是本篇主要分析类加载子系统。

 

Java类加载过程与双亲委派机制_第2张图片

二. 类加载的定义与过程

1. 类加载的定义

  • 类的加载就是把 .class 文件读入内存中,在JVM运行时数据区的堆区中创建对应的 java.lang.Class 对象。
  • Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口。
  • JVM允许类加载器提前进行类加载,如果在预先加载时发现了错误,那么会在程序首次使用该类时报告错误,如果这个类一直没有被程序主动调用,就不会报告错误。

2. 类加载过程

(1)加载

  • 通过全限定类名来获取定义此类的二进制字节流。
  • 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  • 在内存中生成一个代表这个类的 java.lang.Class 对象,作为方法区这个类的各种数据的访问入口。

(2)链接:将加载到JVM中的二进制字节流的类数据信息合并到JVM的运行时状态中。

① 验证:确保Class文件的字节流中包含的信息符合当前虚拟机的要求,包括有文件格式验证、原数据验证、字节码验证等。

② 准备:为类中的所有静态变量分配内存空间,并为其设置一个初始值,进行内存分配的仅包括类变量(被static修饰的变量),而不包括实例变量,实例变量将会在对象实例化的时候随着对象一起分配在Java堆中。

③ 解析:将常量池中的符号引用转为直接引用(得到类或者字段、方法在内存中的指针或者偏移量,以便直接调用该方法),这个可以在初始化之后再执行。解析需要静态绑定的内容,所有不会被重写的方法和域都会被静态绑定。

(3)初始化

  • 类加载过程的最后一步,到了这个阶段才真正开始执行类中定义的Java程序代码

三.类加载器的分类

Java类加载过程与双亲委派机制_第3张图片

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

  • 负责将存放在\lib目录中的,或者被-Xbootclasspath参数所指定的路径中的,并且是虚拟机识别的类库加载到虚拟机内存中。

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

  • 负责加载/lib/ext目录中的、或者被java.ext.dirs系统变量指定的路径中的所有类库,只需要复制JAR文件到扩展目录下就可以。

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

  • 负责加载用户CLASSPATH环境变量指定的路径中的所有类库。如果应用程序中没有自定义过自己的类加载器,这个就是一个Java程序中默认的类加载器。

4. 自定义加载器

  • 基于用户的需求,实现用户的自定义类加载器,一般是为了加密防止反编译,或者是从非标准的来源加载代码。

四. 双亲委派机制

Java类加载过程与双亲委派机制_第4张图片

1. 具体实现:

  • 类加载器收到类加载的请求;
  • 随后将这个请求委托给父类加载器加载,一直向上进行委托,直到启动类加载器;
  • 启动类加载器检查是否能够加载当前这个类,能加载就使用当前加载器,然后结束;
  • 否则就抛出异常,通知子类加载,能加载就加载,否则就层层向下抛异常。

2. 注意点:

  • 双亲委派机制是委派父类;
  • 该机制的父子类与继承无关,只是逻辑上如此调用。

 

你可能感兴趣的:(2020,Java)