【93、类加载的过程】

76 阅读2分钟

类加载是Java虚拟机把class文件中的二进制数据读入内存,并为之创建一个java.lang.Class对象的过程。类加载过程一般分为以下三个步骤:

加载

加载(Loading):加载是类加载过程中的第一个阶段,其主要目的是查找并加载类的二进制数据。加载阶段的任务是由类加载器执行的,由于Java的动态性,一个类可能被多个类加载器加载。Java虚拟机规范定义了以下三种类加载器:
启动类加载器(Bootstrap ClassLoader):它是Java虚拟机实现的一部分,用于加载Java平台核心库,如java.lang和java.util等类。
扩展类加载器(Extension ClassLoader):它用于加载Java平台扩展库,默认从<JAVA_HOME>/jre/lib/ext目录中加载类库。
应用程序类加载器(Application ClassLoader):它是用户自定义的类加载器,默认从classpath中加载类。

链接

链接(Linking):链接分为以下三个步骤:
验证(Verification):验证是确保类的字节码是合法的、符合规范的过程,Java虚拟机规范定义了以下四种验证类型:文件格式验证、元数据验证、字节码验证、符号引用验证。
准备(Preparation):准备阶段是为类的静态变量分配内存并设置默认初始值(例如0null)的阶段,这些内存分配在Java虚拟机的方法区中进行。
解析(Resolution):解析是指将常量池中的符号引用替换为直接引用的过程。在解析阶段会将符号引用转换为直接引用,可以是类、字段、方法等。

初始化

初始化(Initialization):初始化阶段是执行类构造器(即<clinit>()方法)的过程,<clinit>()方法是由编译器自动收集类中所有类变量的赋值动作和静态语句块中的语句合并产生的,编译器按照源代码中的顺序依次执行,<clinit>()方法不需要定义,Java虚拟机会保证在执行<clinit>()方法时,同一时刻只有一个线程执行,因此<clinit>()方法可以看作是多线程环境下的同步锁。

通过以上三个步骤,类加载过程完成后,Java虚拟机会在内存中生成一个java.lang.Class对象,该对象封装了类的各种信息,例如类的名称、父类的名称、方法、字段等。这个java.lang.Class对象就是Java中反射机制的基础。