Java

Java 知识量:11 - 45 - 220

11.2 类加载的各个阶段><

Java类加载的各个阶段- 11.2.1 -

Java类加载的各个阶段主要包括以下步骤:

  1. 加载(Loading):通过类加载器将.class文件加载到内存中,并生成对应的Class对象。

  2. 验证(Verification):验证class文件是否符合Java虚拟机规范,包括语法检查、语义检查等。

  3. 准备(Preparation):为类的静态变量分配内存空间,并设置默认初始值。

  4. 解析(Resolution):将符号引用转换为直接引用,该步骤可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定。

  5. 初始化(Initialization):执行类的初始化代码,例如静态变量的赋值、静态代码块的执行等。

  6. 使用(Using):类加载后可以被使用和访问。

  7. 卸载(unLoading):类从被加载到虚拟机内存开始,到卸载出内存为止的整个生命周期结束。

注意:这些阶段是按照一定的顺序进行的,但是具体的实现细节可能会因为不同的JVM或者JVM版本而有所差异。

加载- 11.2.2 -

Java类的加载是指将Java源代码编译成字节码文件,并将其加载到Java虚拟机(JVM)中,以供JVM运行时使用。Java类的加载是Java虚拟机的重要过程之一,它通常由类加载器(ClassLoader)来完成。

类加载器根据类名来获取类的字节码文件,并将其加载到JVM中。Java类加载器主要有三种类型:

  • 系统类加载器(System Classloader):它是默认的类加载器,用于加载Java核心类库,如rt.jar、resources.jar等。

  • 扩展类加载器(Extension Classloader):它是系统类加载器的子类加载器,用于加载Java扩展类库,如javax.jar、org.class等。

  • 应用类加载器(Application Classloader):它是扩展类加载器的子类加载器,用于加载应用程序的类文件。

验证- 11.2.3 -

Java类的验证是类加载过程中的一个重要步骤,主要验证类的字节码是否符合Java虚拟机规范,以及类中的各种属性是否符合要求。Java类的验证主要包括以下几个方面的内容:

  • 文件格式验证:验证字节码文件是否符合Java虚拟机规范,例如是否符合字节码文件格式规范、是否包含正确的魔术标识符等。

  • 元数据验证:验证类中的元数据是否符合要求,例如类名、父类、接口、字段、方法等是否符合规范,以及类中的各种修饰符和签名的正确性等。

  • 字节码验证:验证类中的字节码是否正确,例如方法体中的指令是否符合规范、操作数栈是否正确等。

  • 符号引用验证:在解析阶段,需要验证符号引用是否正确,例如方法名、变量名、类名等是否符合规范,以及是否存在正确的引用关系等。

Java类的验证是在类加载的过程中进行的,通常由Java虚拟机自动完成,开发人员一般不需要进行干预。如果类加载过程中出现验证错误,可能会导致类加载失败或者运行时异常。

准备和解析- 11.2.4 -

Java类的准备和解析是类加载过程中的两个重要步骤,它们通常在类的初始化之前进行。

准备阶段主要是为类的静态变量分配内存空间,并设置默认初始值。在准备阶段,Java虚拟机会为类的静态变量分配内存空间,并将其初始化为默认值。例如,对于boolean类型的静态变量,它会被初始化为false;对于byte、short、int、long、float、double类型的静态变量,它们会被初始化为0或0.0;对于引用类型的静态变量,它们会被初始化为null。

解析阶段是将符号引用转换为直接引用,这是在类初始化之前进行的。在Java程序中,通常使用符号引用,例如,类名、方法名、变量名等来引用其他类或方法。在类加载过程中,需要将这些符号引用转换为直接引用,即找到实际的对象或方法在内存中的地址。解析过程通常在类初始化阶段之前进行,以便在类初始化阶段可以直接使用这些直接引用。

需要注意的是,在Java类的准备和解析阶段,类还没有被完全加载,因此在这个阶段,不能访问类的任何非静态变量或方法,因为这些变量或方法还没有被加载到内存中。只有当类被完全加载后,才能访问它的非静态变量和方法。

初始化- 11.2.5 -

Java类的初始化是类加载过程中的最后一个步骤,也是最重要的步骤之一。类的初始化是在类加载时执行的一些特殊的操作,例如静态变量的赋值、静态代码块的执行等。

在Java类的初始化阶段,会执行以下操作:

  1. 分配对象的内存空间:Java虚拟机会为每个对象分配内存空间,这个过程是自动完成的,我们通常不需要关心。

  2. 执行静态初始化块:如果类中有静态初始化块,Java虚拟机会在初始化阶段执行它。静态初始化块是在类被加载时执行的,而不是在实例化对象时执行的。

  3. 初始化静态变量:在初始化阶段,Java虚拟机会将静态变量初始化为指定的值。如果静态变量没有被显式地赋值,则会被初始化为默认值。

  4. 执行构造函数:在实例化对象时,Java虚拟机会执行类的构造函数。构造函数是在对象创建时执行的,用于初始化对象的状态。

注意:在Java类的初始化阶段,只有类的静态变量和静态代码块会被初始化,而非静态变量和非静态代码块只有在对象被实例化时才会被初始化。此外,类的初始化阶段是在类被加载后进行的,因此可以在类中使用其他已经加载的类的成员。

类加载的安全性- 11.2.6 -

类加载器负责将.class文件加载到内存中,并生成对应的Class对象。在这个过程中,有一些安全性的考虑因素:

  • 验证:类加载器在加载类时,应确保类文件的格式正确且没有安全问题。Java的验证器会检查字节码是否符合Java虚拟机规范,防止恶意代码的执行。

  • 隔离:不同的类加载器有各自的类加载空间,它们加载的类不会相互影响。这种隔离机制有助于保证系统的安全性。

  • 自定义类加载器:开发者可以创建自定义的类加载器来加载特定的类。这可以用于从特定的来源(例如网络,文件系统等)加载类,或者在加载类时执行特定的检查或操作,以确保类的安全性。

  • 安全策略:Java的安全策略定义了Java运行时环境的权限和约束。通过使用安全管理器,可以控制代码的运行权限,例如文件访问权限,网络访问权限等。