JVM的类加载过程主要可以分为三个主要阶段:加载、链接和初始化,其中链接阶段又可以分为验证、准备和解析三个子阶段。以下是详细的步骤:
1、加载(Loading):
1、通过类的完全限定名(包括包名和类名)查找对应的二进制字节码文件(通常是.class文件)。
2、将这个字节码文件加载到JVM中,并为其生成一个对应的Class对象。这个Class对象作为方法区这个类的各种数据的访问入口。
3、类的加载由类加载器完成,JVM提供了多种类加载器,包括引导类加载器、扩展类加载器、系统类加载器和用户自定义类加载器。
2、链接(Linking):
1、验证(Verification):确保加载的类文件符合JVM规范,包括文件格式验证、元数据验证、字节码验证和符号引用验证。这一步是为了保证加载的类文件不会对JVM造成危害。
2、准备(Preparation):为类的静态变量分配内存,并设置默认的初始值。但这里不包括final修饰的静态变量,因为final修饰的静态变量在编译期就已经分配了值。
3、解析(Resolution):将常量池中的符号引用转换为直接引用。这包括字段解析(将字段名转换为字段在内存中的地址)、接口解析和方法解析(将方法名转换为方法区的入口地址)。
3、初始化(Initialization):
1、初始化静态变量和静态代码块。这一步是执行类构造器方法<clinit>()的过程。
2、如果类有父类,那么会先初始化父类。
3、只有当类被主动使用时(例如创建类的实例、访问类的静态字段或静态方法、反射调用等),才会进行初始化。
在这个过程中,类加载器起到了关键作用,它负责按照双亲委派模型加载类,确保类的唯一性。同时,JVM的类加载机制还提供了动态性,支持运行时加载新的类。
需要注意的是,这些阶段是按顺序开始,但不是严格按顺序进行或完成的。例如,解析阶段在某些情况下可以在初始化阶段之后开始,这是为了支持Java语言的运行时绑定(也称为动态绑定或晚期绑定)。