03 Java 虚拟机是如何加载 Java 类的
Java 引用类型
Java 中的引用类型细分为四种:类,接口,数组类和泛型参数。
因为泛型参数会在编译过程中被擦除,所以 Java 虚拟机实际上只有前三种。数组类是由 Java 虚拟机直接生成的,其他两种则有对应的字节流。
无论是数组类还是其他两种类型,Java 虚拟机都需要对其进行链接和初始化。
加载
加载就是查找字节流,然后据此创建类的过程。数组类由 Java 虚拟机直接生成,其他类则需要 Java 虚拟机借助类加载器来完成查找字节流的过程。
类加载器有很多种,除了启动类加载器以外,其他的类加载器都是 java.lang.ClassLoader 的子类,因此有对应的 Java 对象。这些类加载器都需要先由其他类加载器比如说启动类加载器加载到 Java 虚拟机中,方能执行类加载。
双亲委派机制:每当一个类加载器接收到加载请求时,它会先将请求转发给父类加载器。如果父类加载器没有找到所请求的类的情况下,该类加载器才会尝试去加载。
在 Java 9 之前,启动类加载器负责加载最基础最重要的类。除了启动类加载器之外,还有扩展类加载器和应用类加载器,均由 Java 核心类库提供。
扩展类加载器的父类加载器是启动类加载器。它负责加载相对次要但通用的类。
应用类加载器的父类加载器是扩展类加载器。它负责加载应用程序路径下的类。
Java 9 中扩展类加载器被改名为平台类加载器。Java SE 中除了少数几个关键模块是由启动类加载器加载之外,其他模块均由平台类加载器所加载。
在 Java 虚拟机中,类的唯一性是由类加载器实例以及类的全名一同确定的。
链接
链接是指将创建成的类合并至 Java 虚拟机中,使之能够执行的过程。它可以分为:验证,准备和解析三个阶段。
验证阶段:确保加载类能够满足 Java 虚拟机的约束条件。通常情况下,Java 编译器生成的类文件必然满足 Java 虚拟机的约束条件。(除了字节码注入)
准备阶段:为被加载类的静态字段分配内存,初始化则会在初始化阶段进行。部分 Java 虚拟机还会在此阶段构造其他跟类层次相关的数据结构,比如说用来实现虚方法的动态绑定的方法表。
在 class 文件被加载至 Java 虚拟机之前,这个类无法知道其他类以及其方法和字段所对应的具体地址,甚至不知道自己方法和字段的地址。当需要引用这些成员时,Java 编译器会生成一个符号引用,在运行阶段这些符号引用会定位到具体目标上。
解析阶段就是将这些符号引用解析成为实际引用。
Java 虚拟机规定:如果某些字节码使用了符号引用,那么在执行这些字节码之前,需要完成对这些符号引用的解析。也就是说,在链接过程中不要求一定解析完成。
初始化
在 Java 代码中,初始化一个静态字段,可以声明时赋值,也可以在静态代码块中赋值。
如果被赋值的静态字段被 final 修饰,并且它是基本类型或者字符串时,那么该字段便会被 Java 编译器标记成常量值,其初始化直接由 Java 虚拟机完成。除此之外的直接复制操作每一集静态代码块中的代码,都会被 Java 编译器置于同一方法中,命名为 。
类的初始化,就是为标记常量的字段赋值,以及执行 方法的过程。Java 虚拟机会通过枷锁来确保类的 方法只被执行一次。
举例一下情况会触发类的初始化:
1:虚拟机启动时,初始化用户指定的主类。
2:遇到 new 指令时,初始化 new 指令的目标类。
3:当遇到调用静态方法的指令时,初始化该静态方法所在的类。
4:当遇到访问静态字段的指令时,初始化该静态方法所在的类。
5:子类的初始化会触发父类的初始化。
6:如果一个接口定义了 default 方法,那么实现该接口的类初始化时,会触发接口的初始化。
7:使用反射 API 对某个类进行反射调用时,初始化该类。
问答
Q:新建类,和新建类的数组,初始化过程
新建类的时候,需要加载,链接和初始化。新建类的数组的时候,由于并没有使用类,所以只需要加载该类。如果需要使用该类了,在执行类的链接和初始化。
Q:类的初始化和实例的初始化区别,初始化后的类存储在什么地方
类的初始化只有一次,通过类的加载链接生成对应的数据结构,存储在元空间。实例的初始化可以有多次。
Q:类中的静态字段,如果没有被 JVM 标记为常量,那么如何分配内存
加载类的过程,都会分配内存,只是初始化的时候不一样:一个是在 JVM 中直接复制,一个是在 clinit 方法中复制。
Q clinit 执行时的锁,是什么锁,跟 synchronized 一样吗
clinit 执行时的锁是虚拟机内部锁,和 synchronized 不一样。
总结
本文创作灵感来源于 极客时间 郑雨迪老师的《深入拆解 Java 虚拟机》课程,通过课后反思以及借鉴各位学友的发言总结,现整理出自己的知识架构,以便日后温故知新,查漏补缺。
关注本人公众号,第一时间获取最新文章发布,每日更新一篇技术文章。

03 Java 虚拟机是如何加载 Java 类的的更多相关文章
- 《深入理解Java虚拟机》- Java虚拟机是如何加载Java类的?
Java虚拟机是如何加载Java类的? 这个问题也就是面试常问到的Java类加载机制.在年初面试百战之后,菜鸟喜鹊也是能把这流程倒背如流啊!但是,也只是字面上的背诵,根本就是像上学时背书考试一样. ...
- JAVA之中出现无法加载主类的情况解决方法
j今天打代码的时候出现了无法加载主类的情况,我就收集了一些,java无法加载主类的方法 ava无法加载主类解决办法 今天启动项目,又遇到找不到或无法加载主类的情况,清除项目后无法编译,class文件下 ...
- Java安全之动态加载字节码
Java字节码 简单说,Java字节码就是.class后缀的文件,里面存放Java虚拟机执行的指令. 由于Java是一门跨平台的编译型语言,所以可以适用于不同平台,不同CPU的计算机,开发者只需要将自 ...
- JVM如何加载一个类的过程,双亲委派模型中有哪些方法
1.类加载过程:加载.验证.准备.解析.初始化 加载 在加载阶段,虚拟机主要完成三件事: 1.通过一个类的全限定名来获取定义此类的二进制字节流. 2.将这个字节流所代表的静态存储结构转化为方法 ...
- Java虚拟机(三):Java 类的加载机制
1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...
- 《深入理解java虚拟机》笔记(8)类的加载机制
一.类加载机制 类加载器将类的.class文件中的二进制数据读入到内存中,将其放在方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位 ...
- Java提高篇——JVM加载class文件的原理机制
在面试java工程师的时候,这道题经常被问到,故需特别注意. 1.JVM 简介 JVM 是我们Javaer 的最基本功底了,刚开始学Java 的时候,一般都是从“Hello World ”开始的,然后 ...
- Java --ClassLoader创建、加载class、卸载class
一.java提供了三种ClassLoader对Class进行加载: 1.BootStrap ClassLoader:称为启动类加载器,是Java类加载层次中最顶层的类加载器,负责加载JDK中的核心类库 ...
- 使用javassist运行时动态重新加载java类及其他替换选择
在不少的情况下,我们需要对生产中的系统进行问题排查,但是又不能重启应用,java应用不同于数据库的存储过程,至少到目前为止,还不能原生的支持随时进行编译替换,从这种角度来说,数据库比java的动态性要 ...
随机推荐
- js中(break,continue,return)的区别
break 一般用于跳出整个循环(for,while) continue 跳出本次循环,进入下一次循环 return 只能出现在函数体内,一旦执行return,后面的代码将不会执行,经常用retur ...
- 解决ssh登录慢,等待时间长的问题
有时候在ssh远程登录到其他主机上时发现登录时间太长,经过亲自测试,发现主要有两个问题会导致ssh登录慢: 1.使用了dns反查,这样的话当ssh某个IP时,系统会试图通过DNS反查相对应的域名,如果 ...
- 关于java的自增问题
程序执行结果是0,,,因为count永远是0
- java调用摄像头了
http://www.cnblogs.com/cnweiblog/p/4602207.html
- JavaScript获取时间戳与时间戳转化
第一种方法(精确到秒): var timestamp1 = Date.parse( new Date()); 第二种方法(精确到毫秒): var timestamp2 = ( new Date()). ...
- 【转载】SQLServer中char、varchar、nchar、nvarchar的区别:
(1) 定义: char: 固定长度,存储ANSI字符,不足的补英文半角空格. nchar: 固定长度,存储Unicode字符,不足的补英文半角空格 varchar: 可变长度 ...
- 1305: [CQOI2009]dance跳舞
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 4169 Solved: 1804[Submit][Status][Discuss] Descripti ...
- Android_组件_Activity基础
一.概述 Activity是应用组件,提供了用户交互的窗口.一个应用由多个彼此联系的Activity组成.它大多数情况是全屏窗口显示,也可以作为悬浮窗口 或者 多窗口模式. 二.生命周期 下图是来自A ...
- 利用Filter解决跨域请求的问题
1.为什么出现跨域. 很简单的一句解释,A系统中使用ajax调用B系统中的接口,此时就是一个典型的跨域问题,此时浏览器会出现以下错误信息,此处使用的是chrome浏览器. 错误信息如下: jquery ...
- JZOJ 3487. 【NOIP2013模拟联考11】剑与魔法(dragons)
3487. [NOIP2013模拟联考11]剑与魔法(dragons) (Standard IO) Time Limits: 1000 ms Memory Limits: 131072 KB De ...