专栏首页洁癖是一只狗java虚拟机如何加载一个类

java虚拟机如何加载一个类

现实生活中,我们经常要盖房子,那么盖房子要经过哪些过程呢,首先我们要请建筑师出个方案,然后去市政部门进行报备,验证,通过后才可以盖房子,改好之后还要进行装修,之后才能住人,

其实我们发现盖房子就和java虚拟机中的类加载还是挺像的,从class文件到内存中类,按先后顺序需要加载,链接以及初始化三大步骤,其中,链接过程同样需要验证,而内存中的类没有经过初始化,同样不能使用.接下来我们就详细的说一下每个步骤具体都干些什么

加载

加载就是指查找字节流,并且根据这个创建类的过程,而Java虚拟机是根据类加载器来查找字节流的过程.

我们还以盖房子来说,我要盖的房子就是类,而我们请的建筑师就是我们的类加载器,而现实有许多建筑师,他们都有共同的祖师爷,就相当我们的Java虚拟机中的启动类加载器,启动类加载器是有c++实现。

除了启动类加载器外,还有其他类加载器,且都是java.lang.ClassLoader的子类,这个类加载器需要另外一个加载器加载到java虚拟机,比如启动类加载器,才能执行类加载器

此时我们以建筑师来说,假设他有一个规则,就是不能独自接活,必须由他们的师傅过目,如果师傅看不上的或才能交给他们进行处理,正如我们的Java虚拟机一样,每当一个类加载器接受到加载请求时候,他会先将请求转发给父类加载器,在父类加载器没有找到所请求的类的情况下,该类加载器才能进行加载,这就叫做双亲委派机制,

Java9之前,启动类加载器就是加载比较重要的类,比如存放在lib目录下jar包中的类或有虚拟机参数-Xbootclasspath指定的类,除了启动类加载器,还有另外重要的类加载器,扩展类加载器和应用类加载器,

扩展类加载器,加载一些相对次要的类,但有通用的类,比如存放在lib/ext下的类或有系统变量java.ext.dirs指定的类.

应用类加载器的父类加载器就是扩展类加载器,他负责加载应用程序路径下的类(即虚拟机参数-cp/-classpath,系统变量java.class.path,环境变量CLASSPATH所指定的路径),默认情况下,应用程序包含的类便是由应用类加载器加载的。

java9引入了模块系统,且略微的更改上述的类加载,如扩展类加载器更名为平台类加载器,java se中除了少数几个模块(少数是指比如java.base是由启动类加载器加载),其他模块均由平台类加载器加载,

Java除了提供核心的类加载器,还提供了自定义类加载器,来实现特殊的加载方式,举例来说,我们可以对class文件进行加密,加载时再利用自定义加载器进行解密.

类加载器还提供了另外的功能,命名空间的作用,比如显示生活中,建筑师建造的房子表上自己的名字就是自己的作品,而java虚拟机中,类的唯一性是有类加载器和全类名一同确认的,即便是同一串字节流,经由不同的类加载器加载,就是不同的类,在大型应用中,我们往往借助这个特性来运行同一个类的不通版本。

链接

链接的是指创建的类合并至java虚拟机,使他能够执行,他也分为三个步骤,验证,准备,解析

验证的目的就是确保被加载类能够满足java虚拟机的约束条件,正如我们盖房子,设计的房子要交给市政部分审核,只有审核通过,才能继续建造工作

准备的目的为了加载类的静态字段分配内存,除了分配内存,部分java虚拟机还会在此阶段构造其他类层次相关的数据结构,比如用来实现虚方法的动态绑定的方法表。此时就算改好了毛坯房

在class文件被加载到java虚拟机之前,这个类无法知道其他类及其方法,字段以及具体地址,甚至自己的方法,字段的资质,因此在每当需要应用这些成员时候,java编译器会生成一个符号引用,在运行阶段,这个符号引用一般都能够无歧义的定位到具体的目标。

对于一个方法的调用,编辑器会生成其目标方法所在类的名字,目标方法的名字,接受参数类型以及返回值类型的符号引用,来指代所要调用的方法。

解析就是把符号引用解析成实际的应用,如果符号引用指向一个未加载的类,或者为被加载的字段或方法,那么解析将触发这个类的加载(但未必触发这个链接以及初始化)

符号引用可以理解为某个房子,但是他并一定存在,而把房子的实际地址就是实际的引用,正如我们想要到某个房子,就必须先把房子盖起来,就相当于要加载类

其中我们要注意的是解析未必要在链接中完成,java虚拟机仅仅规定了,如果某些字节码使用了符号应用,那么执行这个字节码之前,要完成这个符号引用的解析

初始化

在java代码中,如果要初始化一个静态子弹,我们可以直接复制,也可以直接在静态代码块中赋值,

但是如果我们给静态变量被final修饰,且是基本类型或字符串的时候,那么该子弹便会被Java编译器标记成常量值,其初始化直接由java虚拟机完成,除此之外的情况以及所有静态代码块的代码块,则会被java编译器放到同一个方法中,并命名为clinit

初始化是类加载的最后一步,便是标记常量字段复制,以及执行clinit方法的过程,java虚拟机会使用锁确保clinit执行一次

初始化完了之后,才能正式的成为可执行的状态,比如我们的房子装修完之后才能真正的主人

最后,类的初始化何时会被触发,JVM规范枚举了下面多种触发情况

  • 当虚拟机启动时,初始化用户指定的类
  • 当遇到用以新建目标实例new指令的时候,初始化new指令的目标类
  • 当遇到静态方法指令时候,初始化静态方法所在的类
  • 当遇到访问静态字段的指令时候,初始化静态字段所在的类
  • 子类的初始化会触发父类的初始化
  • 如果一个接口定义了default方法,那么直接实现或间接实现接口的类的初始化,会触发该接口的初始化
  • 使用反射API对某个类进行反射调用,初始化这个类
  • 当初次调用MethondHandle实例时,初始化该MethondHandle指向的方法坐在的类

本文分享自微信公众号 - 洁癖是一只狗(rookie-dog),作者:洁癖汪

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-01-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java虚拟机--类加载器如何加载一个Class文件

    贾博岩
  • Java虚拟机是如何加载Java类的?

    这事要放在以前还挺简单,亲朋好友搭把手,盖个小砖房就可以住人了。现在呢,整个过程要耗费好久的时间。首先你要请建筑师出个方案,然后去市政部门报备、验证,通过后才可...

    码农架构
  • Java虚拟机是如何加载Java类的?

    上文中说过Java中有两种类型:基本类型和引用类型,而基本类型是由虚拟机预先定义好的,引用类型中的泛型参数又会在编译过程中被擦除,所以加载的对象就剩下类、接口和...

    一觉睡到小时候
  • Java虚拟机--类加载机制

    贾博岩
  • Java虚拟机类加载机制

    看到这个题目,很多人会觉得我写我的java代码,至于类,JVM爱怎么加载就怎么加载,博主有很长一段时间也是这么认为的。随着编程经验的日积月累,越来越感觉到了解虚...

    Java团长
  • Java虚拟机--类加载的时机

    SuperHeroes
  • Java虚拟机--类加载过程

    SuperHeroes
  • Java虚拟机-02:类与类加载器

    摘要:本文主要介绍类加载器、类的唯一性、启动类加载器、拓展类加载器、应用程序类加载器。

    IT云清
  • Java虚拟机类加载机制浅谈

     Java语言是一种编译后再经过解释器执行的过程, 解释器主要就是如何处理解释Class文件的二进制字节流。JVM主要包含三大核心部分:运行时数据区,类加载器和...

    老白
  • Java虚拟机:类加载机制详解

    大家知道,我们的Java程序被编译器编译成class文件,在class文件中描述的各种信息,最终都需要加载到虚拟机内存才能运行和使用,那么虚拟机是如何加载这些c...

    烂猪皮
  • 深入Java虚拟机|类加载机制

    类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。它们开始的顺序如下图所示:

    技术从心
  • Java虚拟机(四):JVM类加载机制

    类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类...

    朝雨忆轻尘
  • Java虚拟机--类加载器源码

    贾博岩
  • 虚拟机类加载机制

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

    YGingko
  • 虚拟机类加载机制

    虚拟机把字节码文件从磁盘加载进内存的这个过程,我们可以粗糙的称之为「类加载」,因为「类加载」不仅仅是读取一段字节码文件那么简单,虚拟机还要进行必要的「验证」、「...

    Single
  • 虚拟机类加载机制

    类从被加载到虚拟机内存开始,到卸载出内存为止,它整个生命周期包括了:加载(Loading)、验证(Verification)、准备(Preparation)、解...

    爱撸猫的杰
  • 虚拟机类加载机制

    转载请注明原帖地址:http://www.cnblogs.com/dongxiao-yang/p/5369195.html

    sanmutongzi
  • 虚拟机类加载机制(2)——类加载器

    《深入理解Java虚拟机》一书中将类的加载过程放到了类加载器前面一节,但在这里我想先讲“类加载器”。在上一篇类加载时机中我们用大量篇幅来讲解了类加载过程中的5个...

    用户1148394
  • Java虚拟机基础——3类加载机制

    在这个框架图很容易大体上了解Java程序工作原理。首先当程序员写好.java文件后,需要先运行(假设该文件为demo.java)

    隔壁老李头

扫码关注云+社区

领取腾讯云代金券