jvm 基础到入门 class文件结构

一 、Jvm 基础到入门

1.1 Jvm 基础到入门

什么是jdk java的开发工具包

什么是jre 运行时环境

什么是jvm java的虚拟机

javac 将.java文件转换为.class文件

java 运行 java文件

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存失败,源站可能有防盗链机制,建议将图片保存下来直接上传下上传(ig2ICF1wDiN0-1641747292729)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220109203606636-16417317686461.png)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220109203606636-164174729827157.png)]

将源代码.java文件 通过javac的指令生成的class文件

通过java指令 将字节码文件.class 进行解析,首先class文件先通过classloader加载到内存中,会用到一些java的相关类库,比如说object 或者String 等等。进行调用字节码的解释器

JIT即时编译器,来对字节码文件进行编译,编译之后,再由执行引擎执行,执行引擎面对的是操作系统和硬件。我们把整个的java指令的这一部分流程称为jvm。

面试题 Java语言是解析执行,还是编译执行?

解析和编译是混合的,针对常用的代码,会把代码做成一种即时编译的,支持本地的,那么在下次使用的时候就不需要解释器对代码进行一句句的解析来执行,执行引擎可以将代码直接交给操作系统。让其进行调用,效率能够提高,当然也不是所有的代码都要被JIT进行即时编译的,原因是java本身需要跨平台。

1.2 从跨平台的语言到跨语言的平台

jvm 是跨语言的平台 java是跨平台的语言

除了java语言 jvm还支持 多门语言 将近 100多种 JVM也是提供了一些规范。

它也帮我们屏蔽了一些操作系统 Linux 或者windows mac
在这里插入图片描述

JVM怎么决定其他语言也可以在JVM上跑 ,就是因为class

其他的语言只要 能生成 class文件 就可以用jvm运行

java程序 ,可以在各种平台是执行 并且不用修改东西

这一点以前的c语言和c++都是做不到的

如果是程序内部编译成的类class 文件 也是可以jvm执行的 所以说java 和jvm 没有任何关系

jvm 是一种 规范 定义了java虚拟机能够执行什么东西

规范在oracle官网

https://docs.oracle.com/javase/specs/index.htm

1.3常见的虚拟机

Hotspot oracle 官方的,我们实验用的 jvm -java-version

命令行窗口 去输入 java version

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GX0vn0QT-1641746615715)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220109204414829-16417322563083.png)]

jrockit -VEA号称最快的jvm 被oracke收购合并 hostpot

TaoBaoVM -hotspot深度定制版本

LiquidVM 直接针对硬件

azul zing 追星垃圾回收的业内标杆 银行用 土豪版本

一般的大厂都不会依赖oracle的东西 都有自己的平台 因为版权问题

java收费 是针对虚拟机来说

Hotspot8 以后 就不升级了 升级需要加钱

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0RfPFjfe-1641746615716)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220106102847933-16414361308491.png)]

二、 Class文件结构

2.1 Class file format

IDEA插件 在file下选择setting 然后在Plugins搜索 Bined 安装

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NnijmkU5-1641746615716)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220106103808644-16414366910032.png)]

图可能不一样 但是名字一样

安装好以后 file - Open as … 选择class文件 就可以看到 Class文件了

Class文件是一组以8个字节为基础单位的二进制字节流。

各项数据会严格的按照顺序紧凑的排列在class文件中

中间没有分隔符,使得class文件存储的内容几乎全部都是程序运行的。

2.2 Classfile 文件结构解析

Java虚拟机规范规定的,class文件格式采用的类似C语言的结构体的伪结构来存储的,这种结构只有两种数据类型。

无符号数 和 表

无符号数:

属于基本数据类型 主要用于描述数字 索引符号 数量值 或者按照UTF-8编码构成的字符串值

数据类型 U1 U2 U4 U8 也只是逻辑上的区分。

U1–表示一个字节

U2–表示二个字节

U4–表示四个字节

U8–表示八个字节

由多个无符号数或者其他表作为数据项构成的复合数据类型。所有的表都习惯以_info结尾 表主要用于描述有层次关系的复合结构数据。 比如 方法、字段 需要注意的是class文件没有分隔符,所以每个二进制数据类型都是严格定义的 具体的顺序如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3OzEKSXL-1641746615717)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220110000019412-16417440212864.png)]

2.2.1 魔数

1 .每一个class文件的头4个字节 被称为魔数 magicNumber

2.唯一作用是 确定这个文件是否为一个能被虚拟机接受的class文件

3.class文件魔数值为 0xCABFABABE 如果这个文件不是以CABFABABE开头 ,那么他就肯定不是 Java的class文件 这也是java.class的识别魔数

很多文件存储标准中都有魔数来识别文件 。

比如 图片的.gif或jpeg等文件头部都存在魔数 是使用魔数识别的而不是文件扩展名识别,这种情况有安全隐患

2.2.2 class文件版本号

紧挨着魔数的4个字节表示class的文件的版本号 版本号:

  1. 次版本号 --minor_version 前2个字节用于表示次版本号

例如:00 00

  1. 主版本号 --major_version 后2个字节用于表示主版本号

例如: 00 34

这个版本号随着jdk版本的不同而表示不同版本的范围。Java的版本号是从45开始的

如果class的版本号超过虚拟机的版本 会被拒绝执行。

JDK1.2 ----0X002E 46

JDK1.3 ----0X002F 47

JDK1.4 ----0X0030 48

JDK1.5 ----0X0031 49

JDK1.6 ----0X0032 50

JDK1.7 ----0X0033 51

JDK1.8 ----0X0034 522.2.3 常量池

2.2.3 常量池

CONSTANT_POOL_COUNT和CONSTANT_POOL

紧跟着魔数与版本号之后的是常量池入口,常量池简单理解为class文件的资源库。

  1. 它是class文件结构中与其他项目关联最多的数据类型

  2. 是占用class文件空间最大的数据项目之一

  3. 是在文件中第一个出现的表类型数据项目。

常量池的数量是不固定,所以在常量池的入口需要放置一个u2类型的数据,代表常量池的计数值CONSTANT_POOL_COUNT。

CONSTANT_POOL_COUNT 从1开始计数的。 class文件结构中只有常量池的容量计数是从1开始的。第0项腾出来满足后面某些指向常量池的索引值的数据,在特定的情况下需要表达“不引用任何一个常量池项目” 把索引值的第0项留给JVM自己用。

CONSTANT_POOL是没有索引值为0的入口的,但是在CONSTANT_POOL_COUNT缺失的第0项也是要被计算在内的。

比如CONSTANT_POOL 中有14项 那么CONSTANT_POOL_COUNT的数值就是15

常量池中主要存放两大类常量:

  1. 字面量: 比较接近java语言层面的常量的概念 比如 字符串 被final关键字声明的常量值。

  2. 符号引用: 属于编译原理方面的概念 包括三项。

    1. 类和接口的全名
    2. 字段的名称和描述
    3. 方法的名称和描述符

在加载class文件的时候 是进行动态连接的。在class文件中不会保存各个方法和字段的最终内存布局信息。(需要经过转换) 当虚拟机运行时 需要从常量池获得对应的符号引用,再在类创建时或者运行时解析并翻译到具体的内存地址中。

CONSTANT_POOL_COUNT 占2个字节 本例中为0x20 转换成十进制为32 说明常量池中有31个常量 ----从1开始计数 其他集合类型均从0开始。 索引值为1-31 第0项常量具有特殊意义。

CONSTANT_POOL 表示的是类型数据集合,在该常量池中,每一项常量都是一个表 共有14种 -----JDK1.7版本,这14种结构的表都是不相同的结构数据。14个表都有一共同的特点,都是由u1的标志位开始的,可以通过这个标志位来判断这个常量属于哪种常量的类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A96UlFBV-1641746615717)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image002-16417441439125.gif)]

2.2.4access_flag

用于表示对该类或接口的访问权限以及该类或接口的属性

![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dMybylru-1641746615718)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/image-20220110000353882-16417442356176-164174434509616.png)](https://img-blog.csdnimg.cn/98c8ec1ab1634cfe8994cd0eb0d92d9d.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAenpzYWl4dWV4aQ==,size_17,color_FFFFFF,t_70,g_se,x_16)

2.2.5 this_class

该this_class 项目的值 必须是constant_pool表中的有效索引,该constant_pool索引处的条目必须是表示此文件定义的类或接口 CONSTANT_Class_info 结构class

2.2.6 super_class

必须是constant_pool表中的有效索引, 如果super_class的值不为0 则constant_pool中的条目必须为CONSTANT_Class_info 结构 这个结构表示此类的文件定义的类的直接超类。直接超类不能在其classfile结构的access_flag项中设置 ACC_FINAL 标志。

其实要描述的意思就是说 如果superclass指代的超类,那么它就不能被final修饰。

2.2.7 ByteCode插件安装

\1. javap指令

2.JBE 插件可以直接修改classfile

3.JClasslib IDEA插件之一

l Javap

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zzBeLTQn-1641746615718)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image002-16417442637617.jpg)]

javap -v 字节码文件的路径

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WA4l2pPL-1641746615719)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image004-164174433663415.jpg)]

从上图可以看出 对文件进行了MD5的加密

Minor Version -----0

Major version -----52

Access_flag -----public super

#4 = Class ----#24 this_class 编号为多少

#5 = Class ----#25 super_class 编号为多少

l JBE

工具 不仅可以查看bytecode 也可以进行修改,可以通过汇编语言编写。

l JClasslib

在setting选项上 选择plugins然后在输入框输入jclasslib

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MM6QSdjv-1641746615720)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image006.jpg)]

如果字节码文件没有生成 可以build Project

选中类名

点击view 选择show bytecode with jclasslib

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qd9KHzo4-1641746615720)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image008.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GU2faMiz-1641746615721)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image010-164174433236014.jpg)]

访问标志为什么是0x0021 这是一个按位与的运算,通过ACC_PUBLIC&ACC_SUPER这两个属性的按位与运算得来的值。使用2个字节来表示,可以代表很多内容。

2.2.8 常量池详细解析常量类型

总共有18个编号的常量类型。

编号1: CONSTANT_UTF8_INFO

TAG1 ------占用一个空间字节

Length: utf-8字符串占用的字节数

Bytes 长度为length字符串

用于表示utf-8的编码的字符串

编号3 CONSTANT_integer_info

Tag3

Bytes 4个字节 Big_Endian(高位在前) 存储int类型的值

编号4 CONSTANT_float_info

Tag4

Bytes 4个字节 Big_Endian(高位在前) 存储float类型的值

编号5 CONSTANT_long_info

Tag5

Bytes 8个字节 Big_Endian(高位在前) 存储long类型的值

编号6 CONSTANT_double_info

Tag6

Bytes 8个字节 Big_Endian(高位在前) 存储double类型的值

编号7 CONSTANT_Class_info

Tag7

Index 2个字节 指向类的全限定名的项的索引

类和接口符号引用

编号8 CONSTANT_String_info

Tag8

Index 2个字节 指向字符串的字面量的索引

编号9 CONSTANT_Fieldref_info

Tag9

Index 2个字节 指向声明字段的类或接口的描述符 CONSTANT_Class_info的索引项

Index 2个字节 指向字段描述符CONSTANT_NameAndType的索引项

字段的符号引用

编号10 CONSTANT_Methodref_info

Tag10

Index 2个字节 指向声明字段的类或接口的描述符 CONSTANT_Class_info的索引项

Index 2个字节 指向字段描述符CONSTANT_NameAndType的索引项

类中方法的符号引用

编号11 CONSTANT_InterfaceMethodref_info

Tag11

Index 2个字节 指向声明字段的类或接口的描述符 CONSTANT_Class_info的索引项

Index 2个字节 指向字段描述符CONSTANT_NameAndType的索引项

接口中方法的符号引用

编号12 CONSTANT_NameAndType

Tag12

Index 2个字节 指向该字段或方法名称常量项的索引
Index 2个字节 指向该字段或方法描述符常量项的索引

字段或方法的符号引用

编号15 CONSTANT_MethodHandler_info

Tag15

Reference_kind 1个字节 1-9之间的一个值 决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为

Reference_index 2个字节 对常量池的有效索引。

表示方法句柄

编号16 CONSTANT_MethodType_info

Tag16

Descriptor_index 2个字节 指向UTF8_info 结构表示的方法描述符

编号18CONSTANT_InvokeDynamic_info

Tag18

Bootstrap_method_attr_index: 2个字节 当前class文件中引导方法表的bootstrap_methods[] 数组的有效索引

Name_and_type_index: 2个字节 指向NameAndType_info 表示方法名和方法描述符。

表示动态方法的调用点。

2.2.8.1 案例解析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cjPVXc1Q-1641746615723)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image004-16417443101928.jpg)]

常量池中有31个常量信息,第一个是Constant_methodref_info 为方法引用信息

#5类名 指向常量池第五个的信息 —Object的类的信息,

#19名字和描述符 CONSTANT_NameAndType_info

在这里插入图片描述

NameAndType_info

在这里插入图片描述

当我们看到init字样的时候,是一个构造方法

当我们看到()V

() 表示方法没有参数

V 表示void 方法没有返回值。

整个常量池在classfile中是如何表示的

cafe babe 0000 0034 0020 0a00 0500 1309 0014 0015 0a00 1600 1707 0018 0700 1901 0006 3c69 6e69 743e 0100 0328 2956 0100 0443 6f64 6501 000f 4c69 6e65 4e75 6d62 6572 5461 626c 6501 0012 4c6f 6361 6c56 6172 6961 626c 6554 6162 6c65 0100 0474

常量池的第一行

从0a00 那么0a对应的是十进制的10 这个10映射到常量表中的Tag10的标志 CONSTANT_Methodref_info;

0005 表示 index 2个字节 指向声明方法的类或接口的描述符#5 CONSTANT_Class_info的索引项。指向#5行的内容。

0013 13 转成十进制是19 指向#19行的内容是,表示的index2个字节 指向字段描述符CONSTANT_NameAndType_info的索引项

那么以上的常量池是5个字节。

常量池的第二行

从09 开始 09对应的是十进制9 这个9映射到Tag9的标志

CONSTANT_Fieldref_info;

0014 对应的十进制是20 对应的#20的内容

0015 对应十进制是21 对应的就是#21的内容

常量池的第三行

从0a开始那么0a对应的是十进制的10 这个10映射到常量表中的Tag10的标志 CONSTANT_Methodref_info;

0016 ----十进制22 对应#22行的内容

0017 ----十进制23 对应的#23行的内容

常量池的第四行

从07开始 对应的tag7 CONSTANT_Class_info

0018 ---- 十进制24 对应着#24的内容 表示的是this_class

常量池的第五行

从07开始 对应的tag7 CONSTANT_Class_info

0019 ---- 十进制25 对应着#25的内容 表示的是super_class

常量池中第六行

01 ----CONSTANT_UTF8_INFO

0006 表示占用的字节数和长度

3c69 6e69 743e 表示字符串内容的字节。init字符串的构造方法

这段总共是9个字节。

常量池的第七行

01 ----CONSTANT_UTF8_INFO

0003 表示常量池第七个常量的字符串长度占用的字节

28 2956 表示 ()V构造方法 V表示无返回值

这段总共6个字节。

Method属性

Method属性包含三个字段值

名称access_flag类型u2 数量1个attributes_count 1

名称 name_index 类型u2 数量1个 attribute_info attributes ----attributes_count

名称 descriptior_index 类型u2 数量1个

descriptior_index

  1. 参数列表(参数类型) 后-返回值

  2. void m() 等同于 ()V

  3. String toString() ->()Ljava/lang/String;

  4. Long pos(int[] arr1,int arr2,long length) ->([IIJ)J

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kl3mPg7f-1641746615725)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image008-164174431019311-164174432289213-164174438289219.jpg)]

[ 一维数组

[[ 表示二维数组

关于attributes_count 附加属性的数量

关于 attributes 附加属性

常量池的第八行

01 ----CONSTANT_UTF8_INFO

0004 表示常量池第八个常量的字符串长度占用的字节

43 6f 64 65 表示 code字符串内容

这段总共是7个字节

Fields属性

名称access_flag 类型u2 数量1个attributes_count 1

同method属性

名称 name_index 类型u2 数量1个 attribute_info attributes ----attributes_count

名称 descriptior_index 类型u2 数量1个

同method属性值。

关于attributes_count 附加属性的数量

关于 attributes 附加属性

第9个常量池LineNumberTable 是在后面要使用的常量的名字,在code当中被引用到。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8YAeeGsw-1641746615727)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image010-164174431019312.jpg)]

第10号常量池LocalVariableTable是在后面要使用的常量的名字,在code当中被引用到。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PvINc7XT-1641746615727)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image012-164174439374120.jpg)]

第11个常量池 指向的字符串面值this

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0X9d5UID-1641746615728)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image014-164174440090321.jpg)]

第十二个常量池 表示整个类的类名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eyNtn7aV-1641746615729)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image016-164174440531922.jpg)]

第13个常量池内容 表示的是main方法的字符串名称

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4x8bNBXG-1641746615729)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image018.jpg)]

第14个常量池内容 表示的是main方法中的参数 字符串数组 无返回值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJGQ2reV-1641746615730)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image020-164174442086224.jpg)]

第15个常量池 main方法的参数名称的字符串字面量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YKGKM1jF-1641746615731)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image022-164174442516725.jpg)]

第16个常量池 mian方法中参数类型的字符串字面量值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lkrXEN3j-1641746615731)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image024-164174442920726.jpg)]

第17个常量池 SourceFile 对应后面的附加属性的SourceFile 表示的是源文件的索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GATkUHEl-1641746615732)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image026-164174443380727.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CDjMdJwh-1641746615733)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image028-164174443757628.jpg)]

第18个常量池内容 表示的是源文件的名称的字符串字面值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LG4VOHqs-1641746615733)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image030-164174444267129.jpg)]

第19个常量池 CONSTANT_NameAndType_info 对应6号常量池构造方法的名字和7号常量池 方法的参数和返回值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gJxxaKkb-1641746615734)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image032-164174444636730.jpg)]

第20个常量池 CONSTANT_Class_info 对应的System类 对应了26号常量池的System的字面值

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TVMQ7Jq0-1641746615735)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image034-164174445040731.jpg)]

第21号常量池 CONSTANT_NameAndType_info 对应的是27号常量池 out字面值属性的名称,对应了28号常量池的PrintStream的类的字符串字面值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aXFIhgVk-1641746615735)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image036-164174445776732.jpg)]

从22号开始到31号,按照字面意思去理解就可以了。

2.2.9 interfaces 和Fields选项 method选项

因为在我们案例中没有声明接口和成员变量,所以对应没有展开选项的。

因为有两个method

在这里插入图片描述

  1. init 无参的构造方法 —默认提供的构造方法

  2. 主函数main

方法中的access_flag

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VBpRZ3R2-1641746615737)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image004-164174449663535.jpg)]

2.2.10 attributes_count 和attribute

附加属性 方法中的附加属性就是code,那么code在这里是比较重要的概念,code是具体代码的实现,当我们写入方法的时候,它能够把方法中代码转化为一条条指令。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qqiUh7z3-1641746615738)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image006-164174449663434-164174451003140.jpg)]

在官方文档中,我们可以看到很多十六进制的数字,那么它们对应方法中code的内容实现。

也可以鼠标右键点击

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O0qSFPIr-1641746615738)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image008-164174449663536-164174451520141.jpg)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nIs5DfEr-1641746615739)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image010-164174449663538-164174451834342.jpg)]

从本地变量表中第0项 放入到栈空间中。

Attributes附加属性

附加属性中 有的代码中存在内容,有的不存在内容

  1. 既有预定义的属性,也可以自定义 java虚拟机会自动忽略它不认识属性

  2. Code 表示的是方法表 方法表能够编译成字节码指令,还存放了操作数栈和局部变量的信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VjNvSLyC-1641746615740)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image012-164174449663537-164174452423243.jpg)]

u2 attribute_name_index 指向常量池中的CONSTANT_UTF8_info 存放的当前属性的名字就是code。

u4 attribute_length 表示的code属性的长度 (不包括前6个字节)。

u2 max_stack 指定当前方法被执行引擎执行的时候,在栈帧中需要分配的操作数栈的大小

u2 max_locals 指定当前方法被执行引擎执行的时候,在栈帧中需要分配的局部变量表的大小

u4 code_length 指定方法字节码的长度, class文件中每条字节码都占用一个字节

u1 code 存放字节码指令本身,它的长度是code_length个字节。

U2 exception_table_length指定异常表的大小

Exception_table异常表 作用对try-catch-finally的描述,可以把它看成是一个数组。每一个数组项都是一个exception_info结构, 一般来说每个catch块对应一个exception_info,编译器也可能会对当前的方法生成一些exception_info.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CXi6nZ34-1641746615740)(C:/Users/HX/Desktop/xuexi/%E6%94%BE%E5%9B%BE/clip_image014-164174449663539-164174452898444.jpg)]

U2 start_pc 是从字节码code属性中的一部分 起始处到当前异常处理器的起始处的偏移量量

u2 end_pc 从字节码起始处到当前异常处理器 末尾的偏移量

u2 handler_pc 是指当前异常处理器用于处理异常(即catch块)的第一条指令相对于字节码开始处的偏移量。

U2 catch_type 是常量池的索引 指向的是常量池CONSTANT-Class_info 数据项,描述了catch块中的异常类型的信息。这个类必须是java.lang.Throwable的或者是它的子类。

总结:

如果偏移量从start_pc到end_pc之间,如果字节码出现了catch_type所描述的异常,那么就跳转偏移量到handler_pc的字节码中去执行。如果catch_type 为0 就代表不引用任何常量池的信息,那么这个exception_info 用于实现finally的子句。

U2 attribute_count 表示的是code属性中存在的其他属性的个数。会出现在 class中的属性,在field属性也有,在method属性也有

Attributes 可以把它看成是个数组,里面存放了code属性的其他属性。

ConstantValue ----字段表 final关键字自定义的常量值

Deprecated —类 方法表 字段表

Exception 异常表

EnclosingMethod 类文件 局部类或匿名类的外部封装方法

InnerClass 类文件 内部类列表

可选属性

LineNumberTable 源码的行号和字节码行号的对应关系 可以把这个属性看成是一个数组,

数组中的每项LineNumberinfo结构描述了一条字节码和源码行号的对应关系

LocalVariableTable 建立了方法中的局部变量与源代码中的局部变量的对应关系。

下一篇
jvm 之类加载和初始化

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zzsaixuexi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值