前言
类加载器(Class Loader)是JVM的一个重要组件,负责将字节码文件(.class文件)加载到内存中。以下是类加载器的详细全面介绍:
一、类加载器种类
JVM中包含三种类加载器:
1.1 Bootstrap类加载器
Bootstrap类加载器是最顶层的类加载器,负责加载JVM核心类库(如java.lang.Object、java.util.ArrayList等)。Bootstrap类加载器是用C++实现的,无法在Java程序中直接引用。
1.2 扩展类加载器(Extension Class Loader)
扩展类加载器是Bootstrap类加载器的子类,负责加载JRE扩展目录(例如$JAVA_HOME/lib/ext)中的类库。
扩展类加载器是用Java实现的,可以在程序中通过java.lang.ClassLoader.getSystemClassLoader().getParent()获取。
1.3 应用类加载器(Application Class Loader)
应用类加载器是扩展类加载器的子类,负责加载应用程序classpath下的类库。
应用类加载器是Java程序默认的类加载器,可以在程序中通过java.lang.ClassLoader.getSystemClassLoader()获取。
二、双亲委派模型
类加载器遵循双亲委派模型(Parent Delegation Model)。当一个类加载器接收到类加载请求时,它首先将请求委托给父类加载器。如果父类加载器无法加载该类,请求会依次向下传递,直到自己尝试加载。这种模型确保了类的唯一性,防止重复加载。
三、类的加载、链接和初始化过程
类的生命周期包括加载、链接(验证、准备、解析)和初始化三个阶段。
3.1 加载
加载阶段是类加载器将字节码文件(.class文件)读入内存的过程。类加载器根据类的完全限定名(包名+类名),从文件系统、网络或其他数据源加载类。
3.2 链接
链接阶段包括验证、准备和解析三个子阶段。
3.2.1 验证
验证阶段主要确保加载的字节码符合JVM规范,没有安全问题。验证包括类结构检查、语义检查、字节码验证和符号引用验证等。
3.2.2 准备
准备阶段为类变量分配内存,并设置默认初始值。
注意,这里的初始值不是程序中设定的值,而是JVM为其指定的默认值。
3.2.3 解析
解析阶段将常量池中的符号引用替换为直接引用。
符号引用是用于描述类、字段和方法的字符串,而直接引用是内存地址或偏移量。
3.3 初始化
初始化阶段执行类构造器方法(<clinit>
),为类变量赋予程序中设定的初始值。
初始化阶段还负责执行静态代码块。该阶段保证了类的初始化操作是线程安全的,只会被执行一次。
总结一下,类加载器是JVM的关键组件,负责将字节码文件加载到内存中。类加载器有三种类型:Bootstrap类加载器、扩展类加载器和应用类加载器。它们遵循双亲委派模型,确保类的唯一性。类的生命周期包括加载、链接(验证、准备、解析)和初始化三个阶段。了解类加载器的种类、双亲委派模型和类的加载、链接和初始化过程,有助于深入理解Java程序在JVM中的执行过程。