jvm之字节码解读——字节码文件结构解析(访问修饰符/本类/父类/成员变量)

根据前文 jvm之字节码解读——认识字节码 ,我们可知,java的字节码文件结构为

前文已经对常量池进行了分析

jvm之字节码解读——认识字节码文件结构解析(常量池)

我们先把常量池的内容贴一下

Constant pool:
   #1 = Methodref          #4.#20         // java/lang/Object."<init>":()V
   #2 = Fieldref           #3.#21         // com/bill/MyByteCodeTest1.a:I
   #3 = Class              #22            // com/bill/MyByteCodeTest1
   #4 = Class              #23            // java/lang/Object
   #5 = Utf8               a
   #6 = Utf8               I
   #7 = Utf8               <init>
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               LocalVariableTable
  #12 = Utf8               this
  #13 = Utf8               Lcom/bill/MyByteCodeTest1;
  #14 = Utf8               getA
  #15 = Utf8               ()I
  #16 = Utf8               setA
  #17 = Utf8               (I)V
  #18 = Utf8               SourceFile
  #19 = Utf8               MyByteCodeTest1.java
  #20 = NameAndType        #7:#8          // "<init>":()V
  #21 = NameAndType        #5:#6          // a:I
  #22 = Utf8               com/bill/MyByteCodeTest1
  #23 = Utf8               java/lang/Object

下面,对紧跟在版本号的字段——Access Flags(访问修饰符)进行分析

Access Flags(访问修饰符)

访问修饰符这个字段比较简单,它的意思这个类的访问修饰符(例如public/static/final)。它占据2个字节

先看看我们这里的访问修饰符是什么

访问修饰符是0x0021(化成2进制就是:0000 0000 0010 0001)

再看以下表

我们对比一下0000 0000 0010 0001,第0位和第5位分别是1,对应的是public和super

public的意思就不多说了,这里ACC_SUPER标志的存在是为了向后兼容Sun较早的编译器为Java编程语言编译的代码,跟jvm如何执行方法是有关的(例如多态的方法执行)

ps:其实这张表我是在网上找的,不知道为什么有2个5/6/7,看上去这样冲突了,如果有人知道答案,可以在评论区说一声

This Class(本类)

这个字段也比较简单,其实就是这个类是哪个,占据2个字节,内容的意义是指向常量池的常量,数值就是常量在常量池的下标,这里为0x0003

我们看一下常量池里第3个常量是什么

 #3 = Class              #22            // com/bill/MyByteCodeTest1

一目了然,其实就是我们自己这个类

Super Class(父类)

这个字段和This Class很像,只是这里描述的是父类的信息,也是占据2个字节,这里为0x0004

我们看一下常量池里第4个常量是什么

 #4 = Class              #23            // java/lang/Object

意思就是,这个类的父类是Object类

Interfaces(接口)

顾名思义,这个字段的意思就是实现了哪个接口,由2+N个字节组成,前2个字节表示接口的个数,后面跟着的内容就是实现的接口(常量池的index)

ps:所以有面试官问你java的类是不是可以实现无限多个接口,你知道该怎么回答了吧?(最多可以实现2的16次方-1个接口)

因为这里没有实现的接口,所以这里的值为0x0000

这个字段比较简单,这里不做详细说明了

Fields(成员变量)

这里Fields的意思就是我们通常理解的field,即成员变量,在我们的例子里,就只有a这个成员变量

这个字段占据的空间是2+n字节,前面2个字节表示成员变量的个数

由于我们这里只有1个成员变量,所以这里的值为0x0001

我们思考一下,一个成员变量的定义是不是这样构成的

访问修饰符(例如public/static/final等)+ 类型(如int/double等)+ 成员变量的名字(这里为a)

所以,要理清楚这个字段是怎么表述的,还要借助另一个表

我们一个个对,access_flags其实就是对应的我们的访问修饰符(例如public/static/final等,跟上文提到的Access_Flag类似),name_index表示的就是成员变量的名字,descriptor_index表示的就是类型(如int/double等),attributes相关的东西我们暂时不看

我们来对一下字节码文件

我们可以看到,这里

access_flags是0x0002(二进制的0000 0000 0000 0010,对比上表,即为private)

 

name_index是0x0005,找到常量池序号为5的常量

#5 = Utf8               a

其实这里表示的意思就是这个字段的名字为“a”

 

descriptor_index是0x0006,找到常量池序号为6的常量

 #6 = Utf8               I

前面有一篇文章介绍了,这个I的代表的意思是int(jvm之字节码解读——认识字节码文件结构解析(常量池)

 

attributes是0x0000,就是说这个成员变量没属性

 

所以,综合上面所述,这里要表达的意思就是

private int a

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值