Java 类加载机制

类从被加载到JVM中开始,到卸载为止,整个生命周期包括:加载、验证、准备、解析、初始化、使用和卸载七个阶段。

其中类加载过程包括加载、验证、准备、解析和初始化五个阶段。

类的加载过程图

类的加载过程

加载

1、通过类加载器,加载.class文件到内存中。

2、将读取到.class数据存储到运行时内存区的方法区。

3、然后将其转换为一个与目标类型对应的java.lang.Class对象实例。这个Class对象在日后就会作为方法区中该类的各种数据的访问入口。

链接

验证

确保被加载的类(.class文件的字节流),是否按照java虚拟的规范。不会造成安全问题

1、文件格式验证:

第一阶段要验证字节流是否符合 Class文件格式的规范, 井且能被当前版本的虚拟机处理。这一阶段可能包括下面这些验证点:

  • 是否以魔数 0xCAFEBABE开头
  • 主、次版本号是否在当前虚拟机处理范围之内 。
  • 常量池的常量中是否有不被支持的常量类型(检查常量tag 标志)。
  • 指向常量的各种索引值中是否有指向不存在的常量或不符合装型的常量 。
  • CONSTANT_Utf8_info型的常量中是否有不符合 UTF8编码的数据
  • Class 文件中各个部分及文件本身是否有被删除的或附加的其他信息

实际上第一阶段的验证点还远不止这些, 这是其中的一部分。只有通过了这个阶段的验证之后, 字节流才会进入内存的方法区中进行存储, 所以后面的三个验证阶段全部是基于方法区的存储结构进行的,不会再直接操作字节流。

2、元数据验证

第二阶段是对字节码描述的信息进行语义分析,以保证其描述的信息符合Java语言规范的要求,这个阶段可能包括的验证点如下:

  • 这个类是否有父类(除了java.lang.0bject之外,所有的类都应当有父类)
  • 这个类的父类是否继承了不允许被继承的类(被finaI修饰的类)
  • 如果这个类不是抽象类, 是否实現了其父类或接口之中要求实现的所有方法
  • 类中的字段、 方法是否与父类产生了矛盾(例如覆盖了父类的final字段, 或者出現不符合规则的方法重载, 例如方法参数都一致, 但返回值类型却不同等)

第二阶段的验证点同样远不止这些,这一阶段的主要目的是对类的元数据信息进行语义检验, 保证不存在不符合 Java语言规范的元数据信息。

3、字节码验证

第三阶段是整个验证过程中最复杂的一个阶段, 主要目的是通过数据流和控制流的分析,确定语义是合法的。符号逻辑的。在第二阶段对元数据信息中的数据类型做完校验后,这阶段将对类的方法体进行校验分析,保证被校验类的方法在运行时不会做出危害虚拟机安全的行为,例如:

  • 保证任意时刻操作数栈的数据装型与指令代码序列都能配合工作, 例如不会出现类似这样的情况:在操作栈中放置了一个 int类型的数据, 使用时却按long类型来加载入本地变量表中。
  • 保证跳转指令不会跳转到方法体以外的字节码指令上
  • 保证方法体中的类型转换是有效的, 例如可以把一个子类对象赋值给父类数据装型,这是安全的,但是把父类对象意赋值给子类数据类型,甚至把对象赋值给与它毫无继承关系、 完全不相干的一个数据类型, 则是危险和不合法的。

即使一个方法体通过了字节码验证, 也不能说明其一定就是安全的。

4、符号引用验证

最后一个阶段的校验发生在虚拟机将符号引用转化为直接引用的时候 , 这个转化动作将在连接的第三个阶段——解析阶段中发生。符号引用验证可以看做是对类自身以外(常量池中的各种符号引用) 的信息进行匹配性的校验, 通常需要校验以下内容:

  • 符号引用中通过字将串描述的全限定名是否能找到对应的类
  • 在指定类中是否存在符合方法的字段描述符以及简单名称所描述的方法和字段 。
  • 符号引用中的类、字段和方法的访问性(privateprotectedpublic)是否可被当前类访问

符号引用验证的目的是确保解析动作能正常执行, 如果无法通过符号引用验证, 将会抛出一个java.lang.IncompatibleClassChangError异常的子类, 如 java.lang.IllegalAccessErrorjava.lang.NoSuchFieldError、java.lang.NoSuchMethodError等。

准备

主要是为类变量(注意,不是实例变量)分配内存,并且赋予初值,此时的赋值是Java虚拟机根据不同变量类型的默认初始值:

如8种基本类型的初值,默认为0;引用类型的初值则为null;常量的初值即为代码中设置的值

1、final static temp = 100,此时temp就是赋值 100。

2、String temp = “123456”,此时temp值就是null。

3、int temp = 100,此时temp值就是0。

解析

将类的二进制数据中的符号引用替换成直接引用(符号引用是用一组符号描述所引用的目标;直接引用是指向目标的指针)

可以认为是一些静态绑定的会被解析,动态绑定则只会在运行时进行解析;静态绑定包括一些final方法(不可以重写),static方法(只会属于当前类),构造器(不会被重写)

在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。

初始化

初始化,则是为标记为常量值的字段赋值的过程。

换句话说,只对static修饰的变量或语句块进行初始化。

如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

涉及问题

一个类的构造器,代码块,静态代码块,成员变量的 的执行顺序。

//父类

//子类

执行结果:

我是父静态成员变量p2

我是父静态代码块1

我是父静态代码块2

我是子静态成员变量c2

我是子静态代码块1

我是子静态代码块2

我是父成员变量p1

我是父代码块1

我是父代码块2

我是父构造器

我是子成员变量c1

我是子代码块1

我是子代码块2

我是子构造器

java类加载过程_面试官:java类的加载过程相关推荐

  1. JVM学习笔记之-类加载子系统,类的加载与类的加载过程,双亲委派机制

    一 类加载器与类加载过程 类加载子系统作用 类加载器子系统负责从文件系统或者网络中加载class文件,class文件在文件开头有特定的文件标识. ClassLoader只负责class文件的加载,至于 ...

  2. Java类的加载过程详解 面试高频!!!值得收藏!!!

    受多种情况的影响,又开始看JVM 方面的知识. 1.Java 实在过于内卷,没法不往深了学. 2.面试题问的多,被迫学习. 3.纯粹的好奇. 很喜欢一句话: 八小时内谋生活,八小时外谋发展. 望别日与 ...

  3. Java类的加载过程,类加载器,双亲委派原则

    Java一个类的加载过程: 1.加载 a.jvm会根据类名找到对应的类文件 b.进行文件内容读取 2.链接 链接主要是验证类中数据是否合法,然后把刚加载进来的类和其他类的关系建立清楚,主要有以下几个步 ...

  4. 深入理解Java虚拟机二(类加载器和类的加载过程)

    类加载器子系统作用 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识. ClassLoader只负责class文件的加载,至于它是否可以运行,则由Ex ...

  5. Java常见面试题:类的加载过程

    程序员看似光鲜的就业前景面前,逃不过的是层层的面试,想要进前沿的大公司没有个五六七八面,是不可能滴!而找工作的首个关卡就是笔试,想要获得高薪工作的小伙伴,先刷一波面试题吧! 今天给大家分享的面试题是- ...

  6. Java 类的加载过程

    Java 类的加载过程 当程序主动使用某个类时,如果该类还没有加载到内存中,则通过以下三个步骤对类进行加载初始化: 类的加载:将类的class文件读入内存,并为之创建一个java.lang.Class ...

  7. Java虚拟机中 类的加载过程

    Java中 类的加载过程 例如下面的一段简单的代码 public class HelloWorld {public static void main(String[] args) {System.ou ...

  8. 中yeti不能加载_第二十章_类的加载过程详解

    类的加载过程详解 概述 在 Java 中数据类型分为基本数据类型和引用数据类型.基本数据类型由虚拟机预先定义,引用数据类型则需要进行类的加载 按照 Java 虚拟机规范,从 Class 文件到加载到内 ...

  9. 卸载java_Java面试必备——类的加载过程

    类的加载过程,类加载过程主要包含加载.验证.准备.解析.初始化.使用.卸载七个方面,下面一一阐述. 一.加载 在加载阶段,虚拟机主要完成三件事: 1.通过一个类的全限定名来获取定义此类的二进制字节流. ...

最新文章

  1. centos 7 安装tomcat
  2. 安装sun-java5-jdk 在ubuntu 9.10 提示无法找到软件包sun-java5-jdk#...
  3. 《可爱的Python》读书笔记(五)
  4. pat 乙级 1021 个位数统计(C++)
  5. python二维向量运算模拟_Python数学基础之向量定义与向量运算(附代码)
  6. linq to xml查询绑定GridView
  7. python open可以打开什么类型文件_Python打开文件open()的注意事项
  8. 一步一步实现KNN分类算法
  9. Python 练习: 打印0到99小于50或大于70的数字
  10. sql盲注 解决_解决SQL盲注和跨站脚本攻击
  11. 网站COM组件调用失败解决办法
  12. malloc函数说明
  13. 灰常实用的一键开关机电路,各位大佬进来mark一下?
  14. 谈谈死链接产生的原因和处理方法
  15. 一个矩形微带贴片天线的调试
  16. ASM磁盘组中的控制文件丢失处理
  17. Lib之过?Java反序列化漏洞通用利用分析
  18. 【Unity入门】软件Unity Hub和Unity的安装和简单尝试
  19. ulong在C语言中的头文件,ULONG没有定义的 有关问题
  20. C#实现全盘扫描,找到符合要求的文件,并把路径写入到TXT中

热门文章

  1. html文字斜体变成正体,$$中的字母如何由斜体变成正体?
  2. c语言编程宝典pdf,C语言编程宝典之一.pdf
  3. python实际应用方面的材料_python应用于哪些方面
  4. “搬砖”机器人,每小时800块!
  5. Linux!为何他一人就写出这么强的系统?
  6. vue饼图组件_vue2.0 自定义 饼状图 (Echarts)组件
  7. 字节跳动python面试题_字节跳动2019两道春招笔试题python解法
  8. as常用固定搭配_英语考试干货!205个常用介词固定搭配
  9. 计算机函数select,请问关于select函数的操作程序?
  10. IDEA无法通过类加载器获取resources文件夹配置文件解决办法