Java类加载基本过程详细介绍

Java类加载是指将class文件从磁盘加载到内存中,并将其转换为Java虚拟机(JVM)内部的数据结构,以便在程序运行时使用。Java类加载包括三个步骤:加载、连接和初始化。下面详细介绍每个步骤的具体过程。

加载

类加载的第一步是加载,其主要目的是通过类的全名查找该类的二进制字节流。在Java中,实现类的加载主要有两种方式:

  1. 类路径(ClassPath)加载

    在Java中,类路径(ClassPath)指定了类文件的搜索路径。类加载器根据类路径来搜索类,当需要加载某个类时,它会从类路径下搜索以该类命名的.class文件,并将这个文件的字节流读入内存,然后创建一个与之对应的Class对象来表示这个类。

  2. 动态加载

    动态加载是指通过Class.forName()方法或ClassLoader.loadClass()方法,动态地从指定的字节码文件中加载类。动态加载通常用于创建 插件系统,实现类似于Hibernate等ORM框架的功能。

连接

类加载的第二步是连接,包括验证、准备和解析三个阶段。

  1. 验证 阶段

    在验证阶段,类加载器会进行字节码验证,以确保.class文件的字节流符合JVM规范,并且不包含任何危险代码。如果验证失败,则会抛出异常,JVM将不允许该类的加载。

  2. 准备 阶段

    在准备阶段,JVM会为加载的每个类创建Class对象,并为这个对象分配内存空间,包括为非static变量分配内存空间和赋初始值(如0或null)。

  3. 解析 阶段

    在解析阶段,JVM会将类和接口中的符号引用解析为直接引用。简单的说,就是将类中用到的其他类的名称转换为可以直接使用的、已经加载过的类的引用。如果解析失败,则会抛出异常。

初始化

类加载的最后一步是初始化。在初始化阶段,JVM会执行类的静态初始化器(static块),这些静态初始化器与类的单独实例无关,只针对整个类。示例代码如下:

public class Demo {
    static int a = 1;
    static int b;

    static {
        b = 2;
        System.out.println("a=" + a + ", b=" + b);
    }

    public static void main(String[] args) {
        System.out.println("a=" + a + ", b=" + b);
    }
}

输出结果为:

a=1, b=2
a=1, b=2

可以看到,在初始化阶段,JVM会按照声明的顺序依次执行静态初始化器中的代码,最终输出" a=1, b=2"。这个过程只会执行一次,且在任意静态变量被访问时都会自动触发。

另外一个示例代码如下:

public class A {
    static {
        System.out.println("A");
    }
}

public class B extends A {
    static {
        System.out.println("B");
    }
}

public class C extends B {
    static {
        System.out.println("C");
    }
}

public class Demo {
    public static void main(String[] args) {
        C c = new C();
    }
}

输出结果为:

A
B
C

这个示例代码中,类C继承于类B,类B又继续于类A。在执行main函数时,首先会JVM会初始化类C,然后初始化类B,并在类B初始化的过程中,顺便也将类A初始化了。可以看到,类的初始化是具有继承性的。

获得了类的Class对象后,就可以创建实例对象,调用对象的方法了。

总结:

Java类加载的过程,包括三个步骤:加载、连接和初始化。加载阶段主要是将类的.class文件加载到内存中,连接阶段包括验证、准备和解析三个阶段,目的是将.class文件中的代码转换为JVM可以理解的形式。初始化阶段则是执行类的静态初始化器。在项目的开发中,对于相对复杂的Java应用程序,需好好理解类的加载过程,更好地掌握应用程序的控制权。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java类加载基本过程详细介绍 - Python技术站

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

相关文章

  • MySQL使用Replace操作时造成数据丢失的问题解决

    MySQL使用Replace操作时造成数据丢失的问题解决攻略 1. 问题描述 在MySQL中,使用REPLACE操作时可能会导致数据丢失的问题。REPLACE操作会先删除原有的记录,然后插入新的记录。如果在删除原有记录和插入新记录之间有其他并发操作修改了数据,就会导致数据丢失的情况发生。 2. 解决方法 为了解决MySQL使用REPLACE操作造成数据丢失的…

    other 2023年10月18日
    00
  • C#取得Web程序和非Web程序的根目录的N种取法总结

    C#取得Web程序和非Web程序的根目录的N种取法总结 在使用C#编写程序时,我们经常需要获取程序的根目录,根据程序是Web程序还是非Web程序,获取根目录的方法也有所不同。下面总结了几种不同情况下获取根目录的方法: 获取Web程序的根目录 方法1:使用HttpContext.Current.Server.MapPath方法 在Web程序中,可以使用Http…

    other 2023年6月27日
    00
  • Ubuntu系统中怎么设置IP地址?

    当在Ubuntu系统中设置IP地址时,可以按照以下步骤进行操作: 打开终端:在Ubuntu系统中,按下Ctrl + Alt + T组合键可以打开终端。 查看网络接口:输入以下命令可以查看当前系统中的网络接口及其配置信息: ifconfig 这将显示所有网络接口的详细信息,包括接口名称(如eth0或wlan0)、MAC地址和IP地址。 编辑网络配置文件:使用以…

    other 2023年7月30日
    00
  • 对layui数据表格动态cols(字段)动态变化详解

    当我们使用layui数据表格时,往往需要动态变化表格的字段,比如说根据不同的搜索条件显示不同的字段等。 在layui中实现动态变化字段,需要以下几个步骤: 1.在 layui 的 cols 数组里,使用一个对象来表示一列,而一个对象可以设置多个属性,比如:field、title、width、sort、type 等等。 2.当需要动态变化字段时,我们需要重新定…

    other 2023年6月27日
    00
  • win10系统右键菜单项里没有“打开方式”选项的解决方法

    下面是详细的攻略。 问题描述 在win10系统中,右键菜单项里没有“打开方式”选项,导致无法通过该选项来选择打开文件的方式,特别是针对不同类型的文件。这可能会导致一些文件无法打开或者打开方式不正确,影响使用体验。 解决方法 方法一:修改注册表 打开注册表编辑器:按下Win+R组合键打开“运行”窗口,输入“regedit”并点击“确定”按钮。 进入注册表项:在…

    other 2023年6月27日
    00
  • MySql利用父id递归向下查询子节点的方法实例

    下面是”MySql利用父id递归向下查询子节点的方法实例”的完整攻略。 什么是父id递归查询? 父id递归查询就是通过父节点的id,递归地向下查询所有子节点的过程。在关系型数据库中常用于查询具有树形结构的数据,如部门树、分类树等。 数据结构设计 父id递归查询需要设计一个具有父子关系的数据结构。在本文中,我们设计了一个product表,用来存储商品的分类信息…

    other 2023年6月27日
    00
  • 专业级的MySQL开发设计规范及SQL编写规范

    MySQL是目前最流行的关系型数据库之一,适用于各种复杂应用程序的构建,但是在实际使用中如何规范MySQL的开发设计和SQL编写就成为了非常重要的问题。以下是针对这一问题的专业级攻略: 1. 数据库设计规范 在进行数据模型设计时,应当符合下列最佳实践: 1.1 概念模型转化为物理模型的顺序 通常应该首先设计概念模型,并对其进行修正和扩展,之后再转化为物理模型…

    other 2023年6月25日
    00
  • Mybatis的collection三层嵌套查询方式(验证通过)

    Mybatis的collection三层嵌套查询方式(验证通过) 在Mybatis中,我们可以使用collection三层嵌套查询方式来处理复杂的数据关系。这种方式可以帮助我们在一次查询中获取多层级的数据,并将其映射到对象模型中。下面是详细的攻略,包含两个示例说明。 步骤一:定义数据模型 首先,我们需要定义数据模型,包括主实体和关联实体。假设我们有三个实体:…

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