详解Java中类的加载与其初始化

详解Java中类的加载与其初始化

Java虚拟机在运行Java程序的时候,会先将程序中所有需要用到的类加载进内存。而类的加载并不仅仅指从磁盘读取class文件并转化为二进制码,还包括链接、初始化等操作。本文会对Java中类的加载、连接、初始化过程进行详细阐述,并通过两条示例进行说明。

类的加载

类的加载通常在Java程序运行过程中进行,加载的方式有以下几种:

  1. 从本地系统中直接加载已经存在的class文件。
  2. 通过网络下载class文件,例如在Java Applet中。
  3. 从zip或jar等归档文件中加载class文件。
  4. 通过专门的类加载器动态生成类字节码,例如JSP页面中的脚本。

Java的类加载器采用的是一种双亲委派的机制。即在类的加载过程中,会先将请求交给父加载器进行处理,如果父加载器无法处理,才由自己来处理。父加载器和子加载器之间是一种包含与继承的关系,子加载器所加载的类可以访问父加载器所加载的类,反之则不行。

类的连接

类的连接可以分为以下三步:

  1. 验证:确保被加载的类的正确性。
  2. 准备:为类的静态变量分配内存,并将其初始化为默认值。
  3. 解析:把类中的符号引用转换为直接引用。

其中验证和解析两步暂不展开说明,准备阶段是为类的静态变量分配内存,并将其初始化为默认值,如int类型的默认值为0,对象类型的默认值为null。注意,除了被声明为final的static变量外,这里所指的“初始化”并不是指类中定义的初始化方法(例如构造方法或静态块)。

类的初始化

只有当对类进行第一次主动使用时,才会触发类的初始化。主动使用包括以下几种情况:

  1. 创建类的实例对象。
  2. 调用类的静态方法或静态变量。
  3. 使用反射方式来创建某个类的对象。
  4. 使用反射方式来调用某个类的静态方法或静态变量。
  5. 初始化某个类的子类。
  6. Java虚拟机启动时被标明的启动类。

类初始化的过程包括以下步骤:

  1. 首先执行所有声明为final的static常量的赋值语句(如果这些常量还未被赋值)。
  2. 执行static块。
  3. 对于非final的static变量,执行赋值语句(如果这些变量还未被赋值)。

在类初始化的过程中,如果某个已被加载的类在其父加载器或其它类加载器中已经被初始化,则不会再次触发初始化。如果一个类在初始化过程中产生了异常,则该类会初始化失败。

示例

下面通过两条示例说明类的加载、连接与初始化过程。

示例一

public class Example {
    static {
        System.out.println("Example's static block");
    }
}

在运行主程序时,虚拟机首先会尝试加载Example类,因为Example类还未被加载过,所以进行了如下过程:

  1. 加载Example类。
  2. 准备Example类的静态变量,此时Example类尚未初始化,且没有父类,所以在准备阶段,jvm会为Example类的静态变量分配内存,并将其初始化为默认值。
  3. 开始初始化Example类,先执行所有声明为final的static常量的赋值语句(如果这些常量还未被赋值),但Example类中并不存在这样的常量。
  4. 执行静态块,输出“Example's static block”。

示例二

public class Example2 {
    public static void main(String[] args) {
        System.out.println("Example2.main");
    }
}

在运行主程序时,虚拟机首先会尝试加载Example2类,因为Example2类还未被加载过,所以进行了如下过程:

  1. 加载Example2类。
  2. 准备Example2类的静态变量,此时Example2类尚未初始化,且没有父类,所以在准备阶段,jvm会为Example2类的静态变量分配内存,并将其初始化为默认值。
  3. 开始初始化Example2类,先执行所有声明为final的static常量的赋值语句(如果这些常量还未被赋值),但Example2类中并不存在这样的常量。
  4. 执行main方法所在的类Example2的静态方法print,输出“Example2.main”。

总结

类的加载、连接、初始化是Java虚拟机运行Java程序的重要流程。类的加载是指在程序运行的过程中,将需要用到的类加载进内存,Java的类加载器采用的是一种双亲委派的机制。类的连接包括验证、准备和解析三个操作。类的初始化只有在主动使用时才会触发,其中被声明为final的static变量除外。在类初始化的过程中,如果某个类已被加载并初始化,则不会再次触发初始化。这里通过两个简单的示例进行了说明。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解Java中类的加载与其初始化 - Python技术站

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

相关文章

  • Java Eclipse进行断点调试的方法

    当然!下面是关于\”Java Eclipse进行断点调试的方法\”的完整攻略,包含两个示例说明。 … … … … … … … … … … … … … … … … … … … … … … … … … … … …

    other 2023年8月20日
    00
  • Android获取其他包的Context实例代码

    Android获取其他包的Context实例代码 在Android开发中,有时候我们需要获取其他应用程序的Context实例,以便进行跨应用的操作。下面是获取其他包的Context实例的代码示例: 示例一:通过包名获取Context实例 String packageName = \"com.example.otherapp\"; Cont…

    other 2023年10月13日
    00
  • win10 RS1技术预览版11103运行界面曝光 含平板模式

    Win10 RS1技术预览版11103运行界面曝光攻略 简介 Win10 RS1技术预览版11103是Windows 10操作系统的一个早期测试版本,该版本的运行界面曝光了一些新的功能和改进。本攻略将详细介绍如何获取和安装该预览版,并展示其中的平板模式功能。 步骤一:获取预览版 首先,访问微软的Windows Insider网站(https://inside…

    other 2023年8月3日
    00
  • visualstudio2017各版本离线安装包获取以及安装教程

    以下是详细讲解“Visual Studio 2017各版本离线安装包获取以及安装教程的完整攻略”的标准Markdown格式文本: Visual Studio 2017各版本离线安装包获取以及安装教程的完整攻略 Visual Studio 2017是微软推出的一款集成开发环境,提供了丰富的工具和功能,用于开发各种类型的应用程序。本文将介绍Visual Stud…

    other 2023年5月9日
    00
  • php页面跳转三种实现方法

    php页面跳转三种实现方法 在开发网站时,经常需要进行页面跳转,以供用户访问不同的页面。本文将介绍三种实现php页面跳转的方法。 Header方式跳转 header() 函数可以用来发送HTTP头信息。当我们需要跳转到另外一个页面时,可以发送HTTP头信息来实现页面跳转。 <?php header("Location: http://www.…

    其他 2023年3月28日
    00
  • 魔兽世界7.3.5奥法怎么堆属性 wow7.35奥法配装属性优先级攻略

    魔兽世界7.3.5奥法怎么堆属性 对于奥术法师来说,输出的强弱与属性堆叠的效果非常相关。以下是奥法配装属性优先级攻略。 属性优先级 奥法的输出主要由智力和暴击率、法强加成三个属性来决定,其他属性相对较为次要。因此属性堆叠应该以智力、暴击优先,其次是法强加成,并搭配一些耐力。 具体优先级为:智力 > 暴击 > 法强加成 > 爆击伤害 >…

    other 2023年6月27日
    00
  • 越狱后iPhone手机不断重启怎么办 越狱后iPhone手机不断重启解决方法

    越狱后iPhone手机不断重启解决方法 问题描述 越狱是指绕过苹果的保护机制,使得用户可以安装来自第三方应用商店的应用。但是,越狱后有时候可能会出现手机不断重启的情况,导致手机无法正常使用。 问题原因 造成越狱后iPhone手机不断重启的原因主要有以下两种: 1.问题应用:越狱后安装了不兼容的应用或者类库,导致系统崩溃,进而导致手机不断重启。 2.不完整的越…

    other 2023年6月27日
    00
  • Android 给控件添加边框阴影效果

    当在Android应用中给控件添加边框和阴影效果时,可以使用以下步骤: 创建一个drawable资源文件,用于定义边框和阴影效果。在res/drawable目录下创建一个XML文件,例如shadow_border.xml。 <shape xmlns:android=\"http://schemas.android.com/apk/res/an…

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