《深入理解JAVA虚拟机(第2版)》- 第6章 - 学习笔记

第6章 类文件结构

6.1 概述

字节码和二级制本地机器码(Native Code)是用来存储程序编译后的结果的,是二种程序存储结构。

6.2 无关性的基石

这里说的无关性,分为:平台无关性和语言无关性。

  1. 平台无关性:JVM和字节码是构成平台无关性的基石。

  2. 语言无关性:所谓语言无关性是说,不是只有Java语言编写的程序才能运行在JVM上,其他语言编写的程序也可以运行在JVM上。构成语言无关性的基石同样是JVM和字节码。

    Java虚拟机提供的语言无关性如图: 在这里插入图片描述 3. JVM不与编程语言绑定,它只与Class文件这种特定的二进制文件格式所关联。

6.3 Class文件的结构

  1. Class文件是一个以8位字节为基本单位的二进制流。
  2. Class文件是采用一种类似C语言结构体的伪结构来存储数据的,所存储的数据只有两类:无符号数和表。
    • 无符号数:

      无符号数属于基本数据类型,可以用来表示数字、索引引用、数量值、UTF-8编码的字符串。我们可以使用u1、u2、u4、u8分别来表示1个字节、2个字节、4个字节、8个字节的无符号数。

    • 表:

      表是由多个无符号数或其他表作为数据项而组成的复合数据类型,通常以“_info”来结尾。

  3. Class文件中头4个字节称为魔数(Magic Number),作用是基于这个魔数来判断当前虚拟机是否能接收这个Class文件。之所以采用这种方式来判断,而不是采用文件扩展名,也是出于安全的考虑,因为文件扩展名可以被随意修改。
  4. 紧跟魔数的后四个字节标识了Class文件的版本,5、6是次版本号(Minor Version),7、8是主版本号(Major Version)
  5. 紧跟主版本号之后的是常量池入口。常量池中的每一项常量就是一张表。常量池中主要存放两类常量:字面量和符号引用。
    1. 字面量

      例如:文本字符串、被final修饰的常量值

    2. 符号引号

      分为以下三类:

      • 类和接口的全限定名(Fully Qualified Name)

      • 字段的名称和描述符(Descriptor)

        这里的描述符是用来描述字段的数据类型。

      • 方法的名称和描述符

        这里的描述符是用来描述方法的参数(个数、类型、顺序)和返回值。

  6. Java代码在进行javac编译的时候,不会像C和C++那样有“连接”步骤,而是在虚拟机进行类加载的时候进行动态连接。
  7. 类的继承关系是通过类索引、父类索引、接口索引集合这三项数据来确定的。
  8. 方法表集合
    • 一个方法对应一个方发表,方发表的结构包括:访问标志(access_flags)、名称索引(name_index)、描述符索引(descriptor_index)、属性表集合(attributes)。 在这里插入图片描述
    • 方法表中有一个属性表集合,其中有一个Code属性是用来存放方法编译后的字节码,这个属性并不是每个方法都有,例如:接口中的方法和抽象类中的抽象方法就没有这个属性。
    • Code属性中字节码指令之后是这个方法的显示异常处理表(简称异常表)集合,异常表对于Code属性来说不是必须的(如果代码中没有异常处理的逻辑就没有这个异常表了)。编译器是采用显示异常处理表来实现Java异常和finally处理机制的,而不是通过简单的跳转命令
    • 属性表集合中还有一个Exception属性,这个属性与Code属性同级,与上边提到的显示异常处理表不同,Exception属性是用来列出方法的要抛出去的受检异常(Checked Exception),也就是方法上throws关键字后边跟着的异常。

6.4 字节码指令简介

  1. Java虚拟机的指令是由操作码(Opcode,一个字节)和操作数(Operands,即操作码的参数)组成的
  2. 由于Java虚拟机是基于操作数栈而不是寄存器的架构,所以大多数指令没有操作数(操作数都存放在操作数栈中了),只有一个操作码。
  3. 操作码的长度为一个字节(能表示的范围是0~255),即指令集中的操作码总数不能超过256。
  4. 加载和存储指令
    • 加载指令是用在从局部变量表中将数据加载到操作数栈中。
    • 存储指令是将操作数栈中的数据存储到局部变量中。
  5. 运算指令
    将两个操作数栈中的数据进行某种特定的运算,并将运算的结果在存储到操作数栈的栈顶。
    运算指令分为:整型数据运算指令和浮点数据运算指令。
  6. 同步指令
    Java虚拟机支持方法级同步一段指令序列同步,这两种同步结构都是通过管程(Monitor)来实现的。
    • 方法级同步
      方法级同步是隐式的,不需要字节码指令来支持,是在方法调用和返回操作中实现的。
    • 一段指令序列同步
      同步一段指令序列,通常使用的是synchronized语句块来实现的,synchronized关键字是通过指令集中monitorenter和monitorexit两个指令来支持的。

上一篇:《深入理解JAVA虚拟机(第2版)》- 第3章 - 学习笔记
下一篇:《深入理解JAVA虚拟机(第2版)》- 第7章 - 学习笔记

  • 25
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cab5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值