JVM(五):类文件结构

这种常量结构代表一个float值,组成如下

  • tag:标志位

  • bytes:类型为u4,按照高位在前存储的float值,所以float占用4个字节

CONSTANT_Long_info

这种常量结构代表一个long值,组成如下

  • tag:标志位

  • bytes:类型为u8,按照高位在前存储的long值,所以long占用8个字节

CONSTANT_Double_info

这种常量结构代表一个double值,组成如下

  • tag:标志位

  • bytes:类型为u8,按照高位在前存储的double值,所以double占用8个字节

CONSTANT_String_info

这种常量结构代表一个字符串,这也是一个索引,指向了CONSTANT_Utf8_info的

  • tag:标志位

  • index:u2类型,指向字符串字面量的索引

CONSTANT_Fieldref_info

这种常量结构用来形容字段的,代表字段的信息,比如字段来自哪个类,名称和类型是什么

  • tag:标志位

  • index:u2类型,指向声明字段的类或者接口描述符的CONSTANT_Class_info(然后CONSTANT_Class_info又指向一个CONSTANT_Utf8_info,CONSTANT_Utf8_info存储的是符号索引)

  • index:u2类型,指向描述字段的CONSTANT_NameAndType_info

CONSTANT_Methodref_info

这种常量结构用来形容方法的,代表方法的信息,比如方法来自哪个类,名称和返回值类型是什么

  • tag:标志位

  • index:u2类型,指向声明方法的类描述符的CONSTANT_Class_info

  • index:u2类型,指向描述方法的CONSTANT_NameAndType_info

CONSTANT_InterfaceMethod-ref_info

这种常量结构也是用来形容方法的,只不过代表的是接口中的放啊

  • tag:标志位

  • index:u2类型,指向声明方法的接口描述符CONSTANT_Class_info

  • index:u类型,指向描述方法的CONSTANT_NameAndType_info

CONSTANT_NameAndType_info

这种 结构是用来形容字段或者方法的名称常量和描述符常量的

  • tag:标志位

  • index:u2类型,指向该字段或者方法名称常量项的索引

  • index:u2类型,指向该字段或者方法描述符的常量项的索引

CONSTANT_MethodHandle_info

这种结构是用来形容给方法句柄的

  • tag:标志位

  • reference_kind:该参数决定了方法句柄的类型,而句柄的类型决定了方法句柄的字节码行为

  • reference_index:常量池的一个有效索引(句柄的作用就是可以访问其他常量池)

CONSTANT_Module_info

这种结构是用来形容模块的,也就是import

  • tag:标志位

  • name_index:指向存储模块名字的CONSTANT_Utf8_info的指针,而CONSTANT_Utf8_info里面是符号引用

CONSTANT_Package_info

这种结构是形容本类的包名称的,对应的就是package

  • tag:标志位

  • name_index:指向存储包名称的CONSTANT_Utf8_info结构

访问标志

常量池之后紧接着的就是访问标志了,访问标志的作用是用于识别一些类或者接口层次的访问信息,比如这个Class是个类还是个接口;访问修饰符是什么;是否是抽象的;是不是被final修饰的

访问标志占用2个字节,对应Class里面的access_flags,类型为u2

具体的标志位如下

| 标志名称 | 标志值 | 含义 |

| — | — | — |

| ACC_PUBLIC | 0x0001 | 是否为Public |

| ACC_FINAL | 0x0010 | 是否被声明为final,只有类可以i设置,接口不可以设置 |

| ACC_SUPER | 0x0020 | 是否允许使用invokespecial字节码指令的新语义 |

| ACC_INTERFACE | 0x0200 | 是不是一i个接口 |

| ACC_ABSTRACT | 0x0400 | 是否为abstract类型,只有抽象类和接口这个标志位才会为true |

| ACC_SYNTHETIC | 0x1000 | 判断该类是否为用户代码产生,如果是的话就为0,不是的话就为1,也就是标识这个类并非由用户代码产生 |

| ACC_ANNOTATION | 0x2000 | 标识这是一个注解 |

| ACC_ENUM | 0x4000 | 标识这是一个枚举 |

| ACC_MODULE | 0x8000 | 标识这是一个模块 |

在access_flags中,其实总共有16个标志位可以使用,而直至JDK9当前只定义了9个,没有使用到的标志位要求一律为0

那么才两个字节的access_flags如何去代表那么多含义呢?

从上表中可以看到,标志名称的标志值并不是连续的,而是有一定距离的,并且该距离通常以位数来拉开,比如说我一个0x8421的access_flags,只可以代表其是一个模块、并且为abstract类型、允许使用invokespecial字节码指令、且为public

类索引、父类索引和接口索引集合

继续往后的部分就是this_class、super_class、interfaces_count和interfaces部分

  • this_class:u2类型,本类索引

  • super_class:u2类型,父类索引

  • interfaces:一组u2类型的数据的集合,接口索引集合

类索引的作用是用于确定这个类的全限定名,而父类索引则是确定这个类的父类的全限定名,由于Java对于类是不允许多继承的,所以父类索引只有一个,除了Object之外,其他的类都有父类,也就是说其他的类的父类索引都不可能为0,而接口索引则存储了该类实现了哪些接口,这些被实现的接口将会按从左到右的顺序排列在接口索引集合中

本类索引、父类索引、接口索引集合都按顺序接着访问标志进行排列

本类索引和父类索引都是u2类型的,里面存储的是指向CONSTANT_Class_info结构的索引,通过该索引是可以找到CONSTANT_Class_info,而CONSTANT_Class_info存储的是指向CONSTANT_utf8_info的索引,CONSTANT_utf8_info里面存储的正式类的全限定名称(一个符号引用)

而对于接口索引集合是分为两部分的

  • interfaces_count:一个u2类型,存

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值