解析Java虚拟机中类的初始化及加载器的父委托机制

解析Java虚拟机中类的初始化及加载器的父委托机制

1. 类的加载过程

  • 类的加载过程包含:加载、连接和初始化三个步骤。
  • 加载过程:通过获取字节流,将.class文件放入内存,并产生一个代表该类的Class对象。
  • 连接过程:分为验证、准备、解析三个阶段,其中解析阶段可能会涉及到类或接口的初始化。
  • 初始化过程:为类的静态变量赋予正确的初始值,进行类构造器()方法的调用。

2. 类的初始化

  • 当Java程序对某个类进行初始化时,如下操作可能会触发类的初始化:
  • 当程序创建某个类的新实例时、
  • 当访问该类的静态变量时、
  • 当调用该类的静态方法时、
  • 当Java虚拟机启动某个类时(如程序的入口方法main())。

  • 类初始化的步骤如下:

  • 确认类已经被加载、连接后;
  • 执行类的()方法——类的构造器方法,为类的静态变量赋值并执行静态块。

3. 加载器的父委托机制

  • 加载器的父委托机制是ClassLoader的读代码时常说的重要特性之一。
  • 当我们需要加载某个类时,先从最近的加载器开始,依次向上委托它的父加载器进行加载。
  • 如果父加载器未能找到该类,那么将会由其子加载器来进行加载。

4. 详细示例

  • 示例1

```
class Person{
static final String WELCOME= "welcome";
static { System.out.println("Initialize for Person"); }
}

class InitDemo{
public static void main(String[] args){
System.out.println(Person.WELCOME);//使用类的静态变量
}
}
```
解析:

当外部程序访问Person.WELCOME变量时,如果类还未初始化,那么此时会先初始化Person类。在Person类初始化过程中,静态块中的代码先被执行,最终输出"Initialize for Person"。当Person类初始化完成后,再输出"WELCOME"。

  • 示例2

```
class A{
static {System.out.println("Initialize for A");}
public static void f1(){}
}

class B{
static {System.out.println("Initialize for B");}
}

public class C{
static {
System.out.println("Initialize for C");
}
public static void main(String[] args){
A.f1();
}
}
```
解析:

当程序运行时,需要加载并执行main()方法,而main()方法中会调用class A的静态方法f1()。根据初始化的条件,程序会先初始化class A,调用静态块输出"Initialize for A"。在A类初始化完成之后,才会进入C类的主方法中,调用静态方法f1()。类B则因为无法访问,未进行初始化。因此输出结果为"Initialize for A"。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:解析Java虚拟机中类的初始化及加载器的父委托机制 - Python技术站

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

相关文章

  • Android实现上拉加载更多以及下拉刷新功能(ListView)

    Android实现上拉加载更多以及下拉刷新功能(ListView)攻略 1. 添加依赖库 首先,我们需要在项目的build.gradle文件中添加下拉刷新和上拉加载更多的依赖库。在dependencies块中添加以下代码: dependencies { implementation ‘com.android.support:appcompat-v7:28.0…

    other 2023年9月7日
    00
  • Objective-C中使用NSString类操作字符串的方法小结

    Objective-C中使用NSString类操作字符串的方法小结 Objective-C中的NSString类提供了许多方法来操作字符串。下面是一些常用的方法和示例说明: 1. 创建字符串 可以使用以下方法来创建字符串: NSString *str1 = @\"Hello, World!\"; // 直接使用字符串字面量创建 NSStr…

    other 2023年8月18日
    00
  • Spring使用注解和配置文件配置事务

    一、Spring使用注解配置事务 在使用Spring进行事务管理时,可以使用注解来标识事务管理的方法。具体步骤如下: 1.引入依赖 在pom.xml文件中,引入Spring事务的依赖: <dependency> <groupId>org.springframework</groupId> <artifactId&gt…

    other 2023年6月25日
    00
  • 详解iOS时间选择框

    详解iOS时间选择框 在iOS开发中,时间选择框是很常见的UI控件之一。我们可以使用UIDatePicker来创建时间选择框。本文将详细介绍如何使用UIDatePicker创建、配置和使用时间选择框。 创建时间选择框 创建UIDatePicker非常简单,可以通过以下代码进行创建: let datePicker = UIDatePicker() 这将创建一个…

    other 2023年6月26日
    00
  • bat 批处理 for 命令快速入门

    BAT 批处理 For 命令快速入门 BAT 批处理 For 命令是 Windows 平台上的批处理脚本语言中的重要组成部分,在批处理脚本中使用 For 命令可以方便地批量处理文件、目录等一系列操作,本文将详细介绍 BAT 批处理 For 命令的基本使用方法。 For 命令的语法说明 for %%变量 in (值1 值2 … 值n) do ( 命令 ) …

    other 2023年6月26日
    00
  • JavaScript变量作用域_动力节点Java学院整理

    当涉及到JavaScript中的变量作用域时,以下是一个完整的攻略,其中包含两个示例说明。 … … 作用域 作用域是指变量在代码中可访问的范围。在JavaScript中,有三种作用域:全局作用域、函数作用域和块级作用域。 1. … 作用域 全局作用域是在整个代码中都可访问的作用域。在全局作用域中声明的变量可以在代码的任何地方访问。 以下是一个示例…

    other 2023年8月10日
    00
  • 使用sevenzipsharp压缩/解压7z格式

    使用sevenzipsharp压缩/解压7z格式 在 .NET 平台中,我们经常需要使用7z格式进行文件的压缩和解压操作。7z 是一种高压缩比的文件格式,因此受到广泛的应用。 本文将介绍如何使用 C# 中的 SevenZipSharp 库进行 7z 格式文件的压缩和解压操作。SevenZipSharp 是基于 7-Zip 引擎的扩展,它提供了一种简单的方式来…

    其他 2023年3月29日
    00
  • Golang如何交叉编译各个平台的二进制文件详解

    Golang是一门跨平台的编程语言,支持Linux、MacOS和Windows等多个操作系统,为了方便用户在不同平台上使用,Golang提供了交叉编译功能,可以在一台机器上编译出不同平台的二进制文件。 以下是Golang交叉编译各个平台的二进制文件的具体步骤: 1. 确定操作系统和CPU架构 在交叉编译之前,需要先确定要编译的目标操作系统和CPU架构,Gol…

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