jvm虚拟机类加载机制详解

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日

相关文章

  • Delphi下OpenGL2d绘图之初始化流程详解

    Delphi下OpenGL2d绘图之初始化流程详解 1. 前言 OpenGL是一种跨平台、开放源码、功能强大的图形编程接口,该接口支持2D/3D图形渲染和可视化。而Delphi是一种用于Windows平台的快速应用程序开发(RAD)工具,可以很好地与OpenGL集成,用于图形编程和可视化。本攻略将全面讲解Delphi下OpenGL2d绘图的初始化流程。 2.…

    other 2023年6月20日
    00
  • vue中slot(插槽)的介绍与使用

    Vue中Slot(插槽)的介绍与使用攻略 什么是插槽? 在Vue中,插槽(Slot)是一种用于在组件中承载内容的机制。它允许我们在组件的模板中定义一些可替换的内容,然后在使用该组件时,将具体的内容传递给插槽,从而实现动态的组件内容。 插槽的基本用法 在组件的模板中,我们可以使用<slot>标签来定义一个插槽。例如: <template&gt…

    other 2023年8月20日
    00
  • centos7.0安装

    CentOS 7.0 安装教程 CentOS是一个从Red Hat Enterprise Linux(RHEL)编译而来的开源操作系统,具有更长的支持周期、更大的软件仓库和更好的稳定性。本篇文章将为大家提供CentOS 7.0的安装教程。 下载CentOS 7.0镜像 首先,我们需要从官网下载CentOS 7.0的镜像文件。可以从如下链接下载最新的CentO…

    其他 2023年3月28日
    00
  • HTML5 图片预加载的示例代码

    下面我就来详细讲解一下“HTML5 图片预加载的示例代码”的完整攻略。 什么是图片预加载? 在网页中,图片通常都会比较大,当用户访问网页时可能会造成页面加载缓慢,甚至出现一段时间的空白,不利于用户体验。为了改善这种情况,我们可以通过预加载图片的方式,在页面完全加载之前,把图片提前加载,保证图片的立刻展现,提高用户体验。 如何实现图片预加载? 第一种方法:使用…

    other 2023年6月25日
    00
  • PHP面向对象程序设计中的self、static、parent关键字用法分析

    PHP面向对象程序设计中的self、static、parent关键字用法分析 1. self关键字 self关键字在类内部使用,指代当前类自身。 使用self可以访问类的常量、静态属性和静态方法。 示例1:访问类的常量 class MyClass { const MY_CONSTANT = 10; public function getConstant() …

    other 2023年6月28日
    00
  • Android统一依赖管理的三种方式总结

    下面是将“Android统一依赖管理的三种方式总结”做完整讲解的攻略: Android统一依赖管理的三种方式总结 在Android开发中,依赖库是非常重要的,它们可以帮助我们更快地完成项目并提高代码的质量。但在Android项目中使用了越来越多的第三方类库,不同的模块和版本之间的依赖关系变得更加复杂,需要一个好的依赖管理工具才能够有效的管理这些依赖关系。这篇…

    other 2023年6月27日
    00
  • 什么是前端开发?

    前端开发的完整攻略包含以下几个步骤: 设计和构思阶段: 在这个阶段,需要设计和构思网站或应用程序的大致架构和样式,包括页面布局,颜色和字体选择等。 示例代码: <!DOCTYPE html> <html> <head> <title>网站标题</title> <meta charset=&qu…

    其他 2023年4月19日
    00
  • Bootstrap实现带暂停功能的轮播组件(推荐)

    下面是关于“Bootstrap实现带暂停功能的轮播组件(推荐)”的完整攻略: 标准Bootstrap轮播组件 首先,我们先来了解一下标准的Bootstrap轮播组件。Bootstrap是一个流行的前端框架,几乎所有的网站前端开发都会用到。Bootstrap提供了很方便的轮播组件,可以在网站中实现图片轮播、新闻轮播等功能。 HTML代码 需要引入Bootstr…

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