周志明先生所著的《深入理解Java虚拟机:JVM高级特性与最佳实践》(购买地址:亚马逊链接),对我学习Java、理解Java之道有非常大的帮助。至今已读过两遍,为了能够融会贯通,加深记忆(人老了记忆力差),便在Blog上记录一些认为该记的东西。
虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换、解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制。
类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括了:加载(Loading),验证(Verification),准备(Preparation),解析(Resolution),初始化(Initialization),使用(Using)和卸载(Unloading)七个阶段。
“解析”阶段不一定按照上图的顺序开始,它在某些情况下可以在初始化阶段之后再开始,这是为了支持Java语言的运行时绑定(也称动态绑定或晚期绑定)。
虚拟机规范中并没有强行约束什么情况下需要开始类加载过程的第一个阶段(加载)。但是对于初始化阶段,虚拟机规范则是严格规定了有且只有四种情况必须立即对类进行“初始化”(而加载、验证、准备自然需要在此之前开始):
1、遇到new、getstatic、putstatic或invokestatic这4条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。生成这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); } }
相关推荐
经典的java虚拟机类加载机制 看完后会有醍醐灌顶的感觉
作者:【郭孝星】http://blog.csdn.net/allenwells 微博:【郭孝星的新浪微博】http://weibo.com/allenwells 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells Github:...
什么是虚拟机类加载机制以及加载过程,以及类加载时机
Java虚拟机类加载顺序,Java虚拟机类加载顺序,Java虚拟机类加载顺序
深入Java虚拟机JVM类加载学习笔记:jvm java classloader 垃圾回收 gc
Java虚拟机类加载机制及双亲委派模型
虚拟机把描述类的数据从Class文件中加载到内存,并对数据进行校验、转换解析和初始化,最终形成可被虚拟机直接使用的Java类型,这就是虚拟机加载机制。
虚拟机将描述类的数据从Class文件加载到内存,并对数据进行校验、准备、解析和初始化,终会形成可以被虚拟机使用的Java类型,这是一个虚拟机的类加载机制。Java中的类是动态加载的,只有在运行期间使用到该类的...
类加载机制, Java 程序 Java是一种面向对象的编程语言,由Sun Microsystems于1995年推出。它是一种跨平台的语言,意味着可以在不同的操作系统上运行。Java具有简单、可移植、高性能和安全性等特点,因此被广泛应用...
Java虚拟机JVM类加载学习笔记
思维导图
在《Java虚拟机类加载机制》一文中详细阐述了类加载的过程,并举了几个例子进行了简要分析,在文章的后留了一个悬念给各位,这里来揭开这个悬念。建议先看完《Java虚拟机类加载机制》这篇再来看这个,印象会比较深刻...
由Java虚拟机自带的默认加载器(根加载器、扩展加载器、系统加载器)所加载的类在JVM生命周期中始终不被卸载。所以这些类的Class对象(我称其为实例的模板对象)始终能被触及!而由用户自定义的类加载器所加载的类会...
CTF逆向-简单虚拟机指令类题目分析CTF逆向-简单虚拟机指令类题目分析
类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。
简单的介绍和描述Java虚拟机类装载:原理、实现与应用
该文档是本人的学习笔记,尚未精修,后续会精修排版. 学习笔记:深入浅出 Java 虚拟机.docx
1. 加载 2. 验证 【连接】 3. 准备 【连接】 4. 解析 【连接】 5. 初始化 6. 使 7. 卸载 1. 遇到new、getstatic、puts
第87节类加载时机00:13:15分钟 | 第88节类加载的过程-加载00:15:15分钟 | 第89节类加载的过程-验证00:10:24分钟 | 第90节类加载的过程-准备00:05:40分钟 | 第91节类加载的过程-解析00:14:04分钟 | 第92节类加载...