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

yizhihongxing

详解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中ArrayList与顺序表的概念与使用实例

    Java中ArrayList与顺序表的概念与使用实例 ArrayList的概念 在Java中,ArrayList是一个基于动态数组实现的List,可以自动扩容,也可以手动指定容量,保证数组中元素的有序性和存在性。 ArrayList在实现上,其底层是通过一个Object数组来实现的,而且ArrayList是有序的,可以通过整数值索引来查找元素,也可以通过Li…

    other 2023年6月27日
    00
  • googlechrome快捷键大全

    以下是详细讲解“Google Chrome快捷键大全的完整攻略,过程中至少包含两条示例说明”的标准Markdown格式文本: Google Chrome快捷键大全 Google Chrome是一款流行的网络浏览器,提供了许多快捷键来方便用户操作。本攻略将介绍Google Chrome的常用快捷键,包括页面导航、标页管理、书签管理、搜索等。同时,本攻略还提供了…

    other 2023年5月10日
    00
  • vue中使用stompjs实现mqtt消息推送通知

    Vue中使用stompjs实现mqtt消息推送通知 简介 在一些实时性较高的应用场景下,常常需要使用到消息推送,而mqtt协议由于其简单实用、扩展性好等优势而逐渐被广泛应用于这方面。本文将介绍如何在Vue框架中使用stompjs库与mqtt协议结合实现消息推送功能。 前置知识 Vue框架基础知识 mqtt协议基础知识 安装依赖 在使用stompjs之前,需要…

    其他 2023年3月28日
    00
  • vscode远程免密登入Linux服务器的配置方法

    下面是“vscode远程免密登入Linux服务器的配置方法”的完整攻略,步骤如下: 1. 安装必要的软件 在进行配置之前,需要先确保本地电脑中已经安装了必要的软件,包括: VS Code编辑器 OpenSSH 客户端 Remote-SSH插件 其中,OpenSSH 客户端是远程访问 Linux 服务器的工具,Remote-SSH插件则是 VS Code 所提…

    other 2023年6月27日
    00
  • 微信小程序中promise的使用

    微信小程序中Promise的使用 在微信小程序的开发过程中,如果需要进行异步操作,就需要使用到Promise。Promise是ES6中新增的特性,它可以让异步操作更加优雅。 Promise的基本使用 Promise有三种状态:pending(进行中)、resolved(已成功)、rejected(已失败)。在使用Promise时,我们需要用到then()和c…

    其他 2023年3月28日
    00
  • python实现写数字文件名的递增保存文件方法

    当我们需要自动保存一些文件的时候,文件名的编号往往需要自动递增。借助 Python 的一些库函数以及一些语法特性,可以方便地实现这个功能。 以下是一个完整的实现攻略: 步骤一:引入必要的库函数 我们需要使用 os 和 shutil 库函数。其中,os 模块能够获取文件和目录的信息,而 shutil 则包含一些高级的文件操作函数。 import os impo…

    other 2023年6月26日
    00
  • IOS中使用UIWebView 加载网页、文件、 html的方法

    下面我将为你讲解如何在iOS中使用UIWebView加载网页、文件、 HTML。 加载网页 在iOS中通过UIWebView加载网页非常简单,只需要使用UIWebView的loadRequest:方法即可。以下是代码示例: NSURL *url = [NSURL URLWithString:@"https://www.example.com&quo…

    other 2023年6月25日
    00
  • Flash单例模式怎么使用? Flash cs6单例模式的实例教程

    Flash单例模式是一种常用的设计模式,主要用于保证一个类只有一个实例,避免多个实例之间的冲突和资源浪费。以下是Flash cs6单例模式的实例教程: 一、单例模式的实现 具体实现单例模式需要遵循以下几个步骤: 创建一个私有静态变量,用于保存类的唯一实例,初始值为null。 创建一个私有静态方法,用于获取类的唯一实例。该方法应当判断唯一实例是否已经存在,如果…

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