Class 文件中描述的各种信息都必须加载到虚拟机中才能运行和使用。而虚拟机怎么加载这些Class 文件呢?Class 文件进入到虚拟机中会发生什么变化呢?

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

与那些在编译器进行连接工作的语言不同,Java 中,类的加载一直到初始化过程都是在运行期间完成的,虽然会损失一点性能,但是却使Java 应用程序具有高度灵活的特性。Java 可以动态扩展的特性就是依赖于运行期动态加载和动态连接这个特点实现的。

类加载的时机

类从被加载到虚拟机内存开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段。其中,验证、准备和解析统称为连接(Linking)。过程如下图所示。

图1 类的生命周期

上述七个过程,除了解析(Resoluton)阶段外,其余的六个过程都必须按部就班的“开始”,之间可能有部分相互交叉的混合执行。 解析过程在某些情况下,可以在初始化阶段之后再开始,这也是为了支持Java 语言的运行时绑定(也称为动态绑定或晚期绑定)。

Java虚拟机规范并没有规定什么时候需要进行类的加载阶段,但是却规定5中情况必须对类进行初始化。

  1. 实例化对象、读写类静态字段、调用静态方法的时候
  2. 使用反射调用的时候
  3. 初始化类时,需要先触发父类的初始化
  4. 虚拟机启动时,会先初始化包含 main() 方法的主类
  5. 使用JDK1.7 的动态语言支持的时候,如果 java.lang.invoke.MethodHandle 实例最后的解析结果REF_getStatic 、REF_putStatic、REF_invokeStatic的方法句柄,句柄对应的类会被初始化
Java虚拟机规范规定有且只有这五种场景中会触发类的初始化,这种行为成为对一个类进行主动引用。除此之外,所有引用类的方式都不会触发初始化,称为被动引用。

被动引用

  1. 通过子类引用父类中定义的静态字段,只会触发父类的初始化。至于是否会触发子类的加载和验证,取决于虚拟机的具体实现(HotSpot不会加载)。
  2. 通过数组定义来引用类,如 A[] ints = new A[10] ,  不会触发A 类的初始化。而是会会触发名为 LA的类初始化。它是一个由虚拟机自动生成的、直接继承于Object 的子类,创建动作由字节码指令 newarray 触发。这个类代表了一个元素类型为 A 的一位数组,数组中的属性和方法都实现在这个类中。Java 语言中数组的访问比C/C++ 安全是因为这个类封装了数组元素的访问方法。
  3. 常量在编译阶段会存入调用类的常量池中,本质上并没有直接引用到定义常量的类,因此不会触发定义常量的类的初始化。
  1. package xiaoye.java;
  2. class Constant{
  3. static {
  4. System.out.print("ConstantClass inited!");
  5. }
  6. public static final String HELLOWORLD = "hehe";
  7. }
  8. public class ConstantClass {
  9. public static void main(String[] args){
  10. System.out.print(Constant.HELLOWORLD);
  11. }
  12. }

接口加载的时机

接口也有初始化过程,但是接口中不能使用static 语句块,但是编译器仍然会为接口生成 <clinit> 类构造器初始化接口中定义的成员变量。 接口与类真正的区别是初始化场景中的第三种情况:当一类在初始化的时候,会要求其所有的父类都初始化完成,但是接口在初始化的时候,并不要求其父接口全部完成了初始化,只有在真正用到了父接口的时候(如引用接口中定义的常量)才会初始化。

深入理解java虚拟机(七)类加载的时机的更多相关文章

  1. 深入理解Java虚拟机(类加载机制)

    文章首发于微信公众号:BaronTalk 上一篇文章我们介绍了「类文件结构」,这一篇我们来看看虚拟机是如何加载类的. 我们的源代码经过编译器编译成字节码之后,最终都需要加载到虚拟机之后才能运行.虚拟机 ...

  2. 深入理解java虚拟机【类加载机制】

    Java虚拟机类加载过程是把Class类文件加载到内存,并对Class文件中的数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的java类型的过程. 在加载阶段,java虚拟机需要完成以下 ...

  3. 深入理解java虚拟机(三)-----类加载机制

    类加载机制jvm把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被jvm直接使用的java类型.在java中,类型的加载.连接和初始化都是在程序运行期间完成的 ...

  4. 深入理解Java虚拟机(八)——类加载机制

    是什么是类加载机制 Java虚拟机将class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这个过程就是类加载机制. 类的生命周期 一个类从加载到内存 ...

  5. 【进阶之路】深入理解Java虚拟机的类加载机制(长文)

    我们在参加面试的时候,经常被问到一些关于类加载机制的问题,也都会在面试之前准备的时候背好答案,但是我们是否有去深入了解什么是类加载机制呢?这段时间因为一些事情在家看了些书,这次就和大家分享一些关于Ja ...

  6. 深入理解java虚拟机(4)类加载的过程

    类加载的过程 ------------------------------------------------------- 0.如下图所示JVM类加载机制分为5个部分:加载.验证.准备.解析.初始化 ...

  7. 深入理解Java虚拟机之类加载机制篇

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

  8. 深入理解Java虚拟机(七)——类文件结构

    Java的无关性 由于计算机领域中有很多操作系统和硬件平台同时在竞争,所以,很多编程语言的程序设计会与其运行的平台和操作系统产生耦合,这样就大大增加了程序员的工作,为了适应不同的平台,需要修改很多代码 ...

  9. 深入理解java虚拟机,类加载

    1,通过使用静态字段,只有真正定义这个字段的类才会被初始化,(子类不初始化,父类初始化 2,new数组,不初始化 3,通过类来调用一些类的常量,可以不初始化类,(常量在编译期,被优化到NotIniti ...

  10. 【深入理解Java虚拟机 】类加载器的命名空间以及类的卸载

    类加载器的命名空间 每个类加载器又有一个命名空间,由其以及其父加载器组成 类加载器的命名空间的作用和影响 每个类加载器又有一个命名空间,由其以及其父加载器组成 在每个类加载器自己的命名空间中不能出现相 ...

随机推荐

  1. linux下启动关闭oracle

    1. linux下启动oracle su - oracle sqlplus /nolog conn /as sysdba startup exit lsnrctl start 2. linux下关闭o ...

  2. LeetCode题解 #1 Two Sum

    在LeetCode做的第一到题 题目大意:给出n个数,在其中找出和为一个特定数的两个数. Input: numbers={2, 7, 11, 15}, target=9Output: index1=1 ...

  3. 塔防游戏 Day1

    1. 创建地图 如上图所示,白色方块为可以放置塔楼的区域,粉红色区域为敌人的行走区域,绿色方块处为起始点,黄色方块点为终止点. 2. 控制游戏的视野 public class ViewScript : ...

  4. Zabbix Proxy 分布式监控

    简介: Zabbix 是一个分布式监控系统,它可以以一个中心点.多个分节点的模式运行,使用 proxy 能降低 Zabbix Server 的压力,当然也带来了成本~ 适用范围:跨机房.跨地域的网络监 ...

  5. mesos in docker

    docker pull mesosphere/mesos-master:1.4.0 docker pull mesosphere/mesos-slave:1.4.0 在Docker中运行Mesos的推 ...

  6. Perl 获取时间函数

    Perl 时间日期 Perl中处理时间的函数有如下几种:    1.time() 函数:返回从1970年1月1日起累计的秒数    2.localtime() 函数:获取本地时区时间(多用这个)    ...

  7. cardBattle游戏启动场景设计

  8. 第五章 大数据平台与技术 第13讲 NoSQL数据库

    NoSQL不是不用SQL,是Not only SQL,不仅仅是结构化的查询. NoSQL兴起的原因 在Web2.0时代新浪一分钟可以发送两万条微博,苹果可以下载4.7万次应用. 数据的高并发性,同时有 ...

  9. Ztree右键事件,如何让指定的子节点不显示右键菜单。

    这里我记录一下我自己的解决方案: 1.首先在Ztree的setting设置中加一个鼠标右键回调函数onRightClick,然后在加一个beforeRightClick(具体含义可以看官方API) v ...

  10. ubuntu server 12.04 jdk,ssh及hadoop配置

    我是在32位的系统下配置的,所以在下载安装文件时候要注意. 第一步:下载并配置JDK 1.下载jdk,这里下载的是jdk1.7.0_65版本的,命令如下 $ wget http://download. ...