JVM学习笔记(二)

上次我们分析了常量池,根据class文件格式,我们看到常量池后面是access flag访问标志,用于表示这个class文件代表的类的访问相关信息,比如是public还是private,是final或者abstract,还有最重要的,是类还是接口等等。具体见下图(图片来源网络)

在这里插入图片描述

访问标志是个U2类型,在我们的例子中,这里的值为0x0021,根据上图,正好是0x0001 & 0x0020的结果,所以该标志位表示的就是ACC_PUBLICACC_SUPERACC_PUBLIC即public,ACC_SUPER如上图的解释,在jdk1.2之后编译出来的类该标志都为真,目前我们先不用深究。

接下来是一个U2的this_class,表示当前类,它指向一个CONSTANT_CLASS_INFO,在例子中该数值为0x0005,从上篇文章的分析中我们可以看到该值为“First”。如下图

在这里插入图片描述

在这里插入图片描述

同理,对于下一个super_class也一样,它表示父类,在本例中它的值是0x0006,根据上篇分析,它对应的值是java/lang/Object。除了Object类所有的类都有父类,所以只有Object类的super_class的值为0,其他类都不为0。

接下来是interfaces_count表示有多少接口。在本列中没有实现接口,所以这值为0x0000,也就是说后面没有interfaces这个属性。

接下来是fields_count,表示字段表集合。这里fields_count的值为0x0000表示没有fields

接下来是method_count,表示方法表集合,它的值为0x0002,表示有两个方法methodsmethods的格式如下图(图片来源

在这里插入图片描述

首先是一个U2的access_flags,它的内容和前面说的常量池后面的access_flags差不多,它代表的内容如下图(图片来源

在这里插入图片描述

我们例子中的值为0x0001,即为public。

接下来是name_index 0x0007,指向常量池第七个参数,即。
descriptor_index 0x0008,指向常量池第八个参数,即()V。这两个参数表示我们例子中的First类的构造方法,例子中没有写构造方法,所以First会使用默认的java/lang/Object的构造方法,没有参数,返回void。

接下来是attributes_count 0x0001,表示有一个属性表,属性表通常的结构如下图(来源地址

在这里插入图片描述

属性表第一个是属性表的名称attribute_name_index,在例子中的值为0x0009,指向常量池中的#9,即Code(每一个属性表的名称都会指向常量池)。

java方法体中的代码都存储在Code属性表中

Code属性表的结构如下图(图片来源与上图一样)
在这里插入图片描述

attribute_length U4 001d 29 属性表长度
max_stack U2 0001 1 操作数栈最大深度
max_locals U2 0001 1 局部变量表所需存储空间
code_length U4 0000 0005 5 字节码长度
code U1 字节码 值如下
2a aload_0
b7 invokespecial
0001 invokespecial的参数 #1 java/lang/Object.;<>V
b1 return
这里表示执行了对象的初始化工作,具体字节码的执行部分我们后面再分析。
exception_table_length U2 0000 0 异常长度
由于长度为0所以这里没有exception_table
接下来又是一个属性表,大家可以试着自己分析,这个属性表为LineNumberTable,用于描述字节码和源码之间的关系,也就是程序报错后可以让我们看到到底是哪行报的错。结构如下图(来源同上)
在这里插入图片描述

line_number_info的结构如下

start_pcu2
line_numberu2

到此方法表分析完毕,对比文件格式表,我们看到方法表之后又是一个attirbutes_count,那我们重复上述工作继续。
attributes_count的值为0001,表示有一个属性表
attribute_name_index的值为000d即13,指向常量池的第十三个值,即SourceFile。SourceFile用于记录生成这个class文件的源码文件名称,它的结构如下

attribute_name_indexu2
attribute_lengthu4
sourcefile_indexu2

按照格式分析如下
attribute_length 0000 0002,表示该属性有两个字节,即000e。
sourcefile_index 000e 即14,指向常量池第十四个值,即First.java

至此整个helloworld就分析完了,有不对的地方欢迎大家指正
.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值