`

《虚拟机类加载机制》笔记:类加载的时机

 
阅读更多

      周志明先生所著的《深入理解Java虚拟机:JVM高级特性与最佳实践》(购买地址:亚马逊链接),对我学习Java、理解Java之道有非常大的帮助。至今已读过两遍,为了能够融会贯通,加深记忆(人老了记忆力差),便在Blog上记录一些认为该记的东西。

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换、解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。

       类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)七个阶段。



“解析”阶段不一定按照上图的顺序开始,它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称动态绑定或晚期绑定)

       虚拟机规范中并没有强行约束什么情况下需要开始类加载过程的第一个阶段(加载)。但是对于初始化阶段,虚拟机规范则是严格规定了有且只有四种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始)

          1、遇到newgetstaticputstaticinvokestatic4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这4条指令的最常见的Java代码场景是:使用new关键字实例化对象、读取或设置一个类的静态字段(final修饰、已在编译期把结果放入常量池的静态字段除外),以及调用一个类的静态方法的时候。

          2、使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有初始化,则初始化。

          3、当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发父类的初始化。

          4、当虚拟机启动时,用户需要指定一个要执行的主类(包含main方法的类),虚拟机会先初始化这个主类。

对于这四种会触发类进行初始化的场景,虚拟机规范中使用了一个很强烈的限定语“有且只有”,这四种场景中的行为被称为对一个类进行主动引用。除此之外所有引用类的方式,都不会触发初始化,称为被动引用。被动引用如以下的代码所示:

 

public class SuperClass {
	static {
	        System.out.println("superclass init");
	}
	public static int value=123;
}
public class SubClass extends SuperClass{
	static {
		System.out.println("subclass init");
	}
}
public class Test {
	public static void main(String[] args) {
               //以下不会触发SubClass的初始化。对于静态字段,只有直接定义这个字段的类才会被               //初始化。所以这里,只有父类被初始化。
	       System.out.println(SubClass.value);
	}
}
public class Test {
	public static void main(String[] args) {
		//这里并没有直接引用SuperClass类,而是用到了另一个类型(代表一个以SuperClass                //为元素类型的数组)
		SuperClass[] sca=new SuperClass[10];
	}
}

 

public class ConstClass {
	static {
		System.out.println("ConstClass init");
	}
	public static final String HELLOWORLD="hello world";
}
public class Test {
	public static void main(String[] args) {
		//虽然在这里的代码中引用了ConstClass中的常量HELLOWORLD,但是在编译阶段已将
		//此常量的值存储到了Test类的常量池中,对常量ConstClass.HELLOWORLD的引用实际                //都被转化为Test类对自身常量池的引用了。
		//这两个累在编译成Class后就不存在任何联系了。
		System.out.println(ConstClass.HELLOWORLD);
	}
}

 

 

  • 大小: 23.7 KB
分享到:
评论

相关推荐

    jvm笔记记录.docx

    ### JVM基础知识及类加载机制详解 #### Java程序的运行流程 Java程序的执行流程主要包含以下几个步骤: 1. **编译**: 将`.java`源文件编译为`.class`字节码文件。 2. **打包**: 将多个`.class`字节码文件打包为一...

    安卓逆向学习笔记之Dalvik下dex加载流程和通用脱壳点.docx

    - **类加载器的角色**: Android使用自定义的类加载机制来处理DEX文件。类加载器负责将DEX文件中的类加载到虚拟机中。 - **多DEX文件的支持**: 较新的Android版本支持将多个DEX文件打包到同一个APK中。当加载这些额外...

    这是一个关于JVM的笔记,可以帮助你

    这个笔记将深入探讨JVM的工作原理、内存管理、类加载机制以及性能优化等方面,帮助你更好地理解和掌握Java编程的底层运行机制。 首先,JVM的结构包括堆、栈、方法区、本地方法栈和程序计数器等组件。每个部分都有其...

    Android插件化开发笔记

    通过自定义类加载器,可以控制插件的加载时机和方式,使得插件的类能在运行时被正确解析和执行。 3. **插件与宿主的交互** 宿主和插件之间的交互通常通过接口实现。宿主提供API供插件调用,而插件通过注册或回调...

    JAVA 面试入坟系列(思维导图) By_萧曵丶.pdf

    #### 2.3 类加载机制 - **类的生命周期**:加载、验证、准备、解析、初始化、使用、卸载七个阶段。 - **类的初始化时机**:Java虚拟机在首次主动使用类时进行初始化。 ### 3. Java面试相关 #### 3.1 常见面试题 ...

    6.1.5.JVM终结篇笔记1

    【标题】:“6.1.5.JVM终结篇笔记1”主要探讨了JVM的深入理解和垃圾收集(GC)优化,包括GC发生时机、实验环境准备、GC日志及其分析。 【描述】:本笔记首先从宏观角度重新认识JVM,强调了JVM的物理结构,特别是...

    java学习笔记-基础

    ### Java学习笔记——基础知识详解 #### 一、Java开发环境(JDK)与运行环境(JRE) Java技术的核心在于其强大的跨平台能力,这主要得益于Java的两大环境:JDK(Java Development Kit)和JRE(Java Runtime ...

    B站王道操作系统学习笔记.pdf

    《B站王道操作系统学习笔记》是一份系统阐述操作系统的文档,涵盖了进程管理、内存管理、文件管理等多个关键领域。操作系统作为计算机系统的核心软件,负责管理和控制计算机系统中的各种硬件资源和软件资源,提供给...

    Java学习笔记.doc

    运行Java程序时,JVM首先启动,然后加载并执行指定的.class文件,如果类不在当前目录或系统类库中,就需要提供完整的类路径。 总之,Java的学习涵盖了从基础语法、面向对象特性、内存管理、开发环境配置、程序打包...

    android 学习心得

    ### 十一、Android Activity和Intent机制学习笔记 - **Intent**:用于在Activity之间传递信息的意图对象,可以启动新的Activity、服务等。 - **显式Intent**:直接指定了要启动的目标组件。 - **隐式Intent**:通过...

Global site tag (gtag.js) - Google Analytics