jvm虚拟机类加载机制详解

yizhihongxing

jvm虚拟机类加载机制详解

什么是类加载

在 Java 程序中,类的加载是指将类的 .class 文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个 java.lang.Class 对象,用来封装在方法区内的数据结构。ClassLoader 类是用来加载 Java 类的类加载器。

类加载的步骤

Java 虚拟机将符号引用转换成直接引用的过程分为以下 5 个阶段。

  1. 加载:在这个阶段,ClassLoader 会通过全限定名来读取 .class 文件,并生成对应的字节数组。

  2. 链接:在加载阶段后,虚拟机会将这个类的二进制数据中的符号引用替换成直接引用,包括以下三个阶段:

  3. 验证:这个阶段确保所导入的类是能够正确执行,且与当前运行环境的其他代码并存是安全的。在这个阶段中,将会检查 .class 文件的合法性,并且验证类中的各种信息是否符合 Java 虚拟机规范,例如类是否继承于指定的类或实现了接口。

  4. 准备:为类变量(static 变量)分配内存,设置初始值。

  5. 解析:将符号引用转换成直接引用。

  6. 初始化:当 Java 程序运行至这个阶段时,就会执行类构造器 <clinit> 方法的内容,为类静态变量分配内存并设置初始值,这些静态变量所使用的值在代码中是已经明确写好的,因而在这个时候称为确定值。也就是说,在初始化阶段,类变量的初始化是实际被执行的操作,并且是在这个阶段对其赋值的。对于实例变量的初始化,是在对象实例化时进行的。

示例说明

示例一

下面的代码演示了类的初始化顺序。

public class Example {
    public static void main(String[] args) {
        new SubClass();
    }
}

class SuperClass {
    static {
        System.out.println("SuperClass init");
    }
}

class SubClass extends SuperClass {
    static {
        System.out.println("SubClass init");
    }
}

输出结果为:

SuperClass init
SubClass init

在以上代码中,main 方法创建了一个 SubClass 的实例。在这个过程中,会触发对 SubClass 类的初始化,而 SubClass 继承自 SuperClass,因此会先初始化 SuperClass 类。

示例二

下面的代码演示了类的动态加载。

public class Example {
    public static void main(String[] args) throws Exception {
        Class clazz = Class.forName("com.example.SubClass");
        System.out.println(clazz.getClassLoader());
    }
}

class SubClass {
}

输出结果为:

sun.misc.Launcher$AppClassLoader@18b4aac2

在以上代码中,main 方法加载了 SubClass 类,并输出其类加载器。总结一下以上示例:

  • 当访问类的静态变量时,会触发对该类的初始化。
  • 当通过 Class.forName 方法加载类时,也会触发对该类的初始化。
  • 类的加载由实现类消除,可以通过重写 systemClassLoader 完成。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:jvm虚拟机类加载机制详解 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • 如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框

    Bootstrap的modal组件可以帮助我们创建自定义的alert、confirm和modal对话框。下面是使用Bootstrap的modal组件自定义alert、confirm和modal对话框的完整攻略: 准备工作 在进行下一步之前,需确保已经引入了Bootstrap框架。如未引入,可以在head标签中添加以下代码: <link rel=&quo…

    other 2023年6月26日
    00
  • freemodbus线圈中的位操作

    我将为您提供解决 freemodbus 线圈中的位操作的完整攻略,包括问题的原因、解决方法和两个示例说明。 问题原因 在 freemodbus 中,线圈是一个二进制位数组,每个位表示一个开关状态。在进行位操作时,需要注意以下问题: 位的编号从 0 开始,而不是从 1 开始。 位的操作是按位进行的,而不是按字节进行的。 解决方法 为了解决这个问题,可以使用以下…

    other 2023年5月5日
    00
  • 平均精度(averageprecision)计算

    以下是关于“平均精度(average precision)计算”的完整攻略,包含两个示例。 平均精度(average precision)计算 平均精度(average precision)是一种用于评估信息检索系统的指标。它是通过计算每个查询的精度和召回率曲线下面积来计算的。平均精度是信息检索系统性能的重要指标之一,通常用于比较不同系统的性能。 1. 计算…

    other 2023年5月9日
    00
  • Scala之Object的具体使用(小结)

    下面是详细讲解“Scala之Object的具体使用(小结)”的完整攻略: 1. Object的介绍 在Scala中,Object是一种特殊的class,它只有一个单例实例。我们可以把Object看成是一些静态的方法和属性的集合,这些方法和属性可以通过Object访问,而不需要对Object进行实例化操作。因此,Object可以看成是Scala中的静态类。 2…

    other 2023年6月26日
    00
  • C++中的各种容器的使用方法汇总

    C++中的各种容器的使用方法汇总 本攻略介绍了C++中的常用容器的使用方法,包括:数组,向量,列表,栈,队列,映射和集合等。 数组 数组是C++中最基本的容器,它存储固定大小的相同类型元素。数组的大小在声明时就已经指定,而且不能随意改变。 以下是数组的基本定义和初始化方法: int arr[5]; //定义一个数组,包含五个整数元素 int arr[5] =…

    other 2023年6月26日
    00
  • coo是什么职位?

    COO是指Chief Operating Officer,即首席运营官,是公司中负责运营层面的高管职位。他/她负责公司的日常运营、管理和商业战略的实施。以下是详细讲解coo职位的攻略: 什么是COO职位? COO职位通常是一家公司的高管层中排名第二的职位,直接向CEO汇报。COO代表公司的管理层面,负责日常运营、人力资源管理、营销和业务发展等方面的工作。 C…

    其他 2023年4月16日
    00
  • 解决MySQl查询不区分大小写的方法讲解

    解决MySQL查询不区分大小写的方法讲解 在MySQL中,默认情况下,查询是区分大小写的。但是有时候我们希望进行大小写不敏感的查询,本文将详细介绍两种解决MySQL查询不区分大小写的方法。 方法一:使用COLLATE关键字 COLLATE关键字用于指定排序规则,我们可以使用COLLATE关键字来实现大小写不敏感的查询。 示例一:查询名字为\”John\”的用…

    other 2023年8月17日
    00
  • 苹果iOS9.3.2 Beta1开发者预览版固件更新发布 bug修复和改进

    苹果iOS9.3.2 Beta1开发者预览版固件更新发布 bug修复和改进攻略 苹果公司于2016年4月7日发布了iOS 9.3.2 Beta1 开发者预览版固件更新。此次更新修复了若干软件缺陷和提高了性能优化,让用户体验更加完善。 安装iOS 9.3.2 Beta1预览版 要安装 iOS 9.3.2 Beta1 预览版,首先要成为苹果开发者,然后就可以前往…

    other 2023年6月26日
    00
合作推广
合作推广
分享本页
返回顶部