asm代码解析看java字节码结构

本文通过asm库解析.class文件,详细介绍了字节码结构,包括魔数、常量池、基本信息、field&method和attribute部分,分析了各类常量、访问标志、类名、接口、字段和方法等细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

根据asm对字节码的解析,可以分析出.class文件的字节码结构

结构示意图如下

在这里插入图片描述

  1. 4个byte为cafe babe,2个byte为minor 和major
  2. 常量池分两部分,2个byte的常量池大小和内容
  3. 2个byte的access flag,2个byte的class名,2个byte的super class名,2个byte的interface数量,及interface
  4. 2个byte的field数量及field内容
  5. 2个byte的method数量及method内容
  6. 2个byte的i值,2个byte的attribute名,4个byte的attribute长度及attribute内容

下面分别来看各个部分
cafe babe为魔数,写死的,minor version和major version也好理解

常量池部分

常量池大小即常量的个数,具体的每个常量部分第一个byte为类型,后面为常量内容,类型总共有17种,根据占据byte个数不同可以分为2类,固定长度的和可变长度的

其中固定长度的有4种
  1. 4个byte:
  • CONSTANT_FIELDREF_TAG
  • CONSTANT_METHODREF_TAG
  • CONSTANT_INTERFACE_METHODREF_TAG
  • CONSTANT_INTEGER_TAG
  • CONSTANT_FLOAT_TAG
  • CONSTANT_NAME_AND_TYPE_TAG
  • CONSTANT_DYNAMIC_TAG
  • CONSTANT_INVOKE_DYNAMIC_TAG
  1. 8个byte:
  • CONSTANT_LONG_TAG
  • CONSTANT_DOUBLE_TAG
  1. 3个byte:
  • CONSTANT_METHOD_HANDLE_TAG
  1. 2个byte:
  • CONSTANT_CLASS_TAG
  • CONSTANT_STRING_TAG
  • CONSTANT_METHOD_TYPE_TAG
  • CONSTANT_PACKAGE_TAG
  • CONSTANT_MODULE_TAG
可变长度的只有一种CONSTANT_UTF8_TAG

其占用byte情况为:2个byte+2个byte所指定的长度个byte,两种情况如下图
在这里插入图片描述

基本信息

access flag占2个byte,class name和super class都占2个byte,其值为常量池中的字符串索引(后面简称常量索引),也就是说具体的字符串需要回常量池中查找,interface数量占2个byte,后续每个interface名也占2个byte,也为常量索引

field&method部分

  1. 2个byte的access flag
  2. 2个byte的name,值为常量索引
  3. 2个byte的描述
  4. 2个byte的attribute数量
  5. 每个attribute有2个byte的name,值为常量索引,4个byte的属性长度,及对应个byte的attribute

在这里插入图片描述

attribute部分

attribute基本格式为2个byte的name,值为常量索引,4个byte的attribute内容长度
在这里插入图片描述
根据attribute name的不同,attribute结构总共有17种(asm1.7中的)

  1. SOURCE_FILE为2个byte,值为常量索引
  2. INNER_CLASSES为2个byte的内部类个数,每个内部类为2个byte name, 2个byte的外部类,2个byte的内部类,它们都为常量索引,2个byte的access flag在这里插入图片描述
  3. ENCLOSING_METHOD为2个byte的外部类名,值为常量索引,2个byte的方法名eclosing的话,值为常量索引,此常量索引偏移2个byte即为descripter
  4. NEST_HOST为2个byte的类名,值为常量索引
  5. NEST_MEMBERS为2个byte的个数,每个MEMBER为2个byte的常量索引
  6. SIGNATURE为2个byte的类泛型描述,值为常量索引
  7. DEPRECATED和SYNTHETIC都可以不占其它byte,描述access flag信息
  8. SOURCE_DEBUG_EXTENSION为attribute length个byte长度,为字符串(此处不是常量池索引)
  9. MODULE_MAIN_CLASS为2个byte的main class,为字符串索引
  10. MODULE_PACKAGES为2个byte的package count,每个package为2个byte的常量索引
  11. BOOTSTRAP_METHODS拼装成attribute的字节数组
  12. MODULE为2个byte的name, 为字符串索引,2个byte的access flag,为字符串索引,两个byte的version,如果MODULE_MAIN_CLASS不为空,则接下来有require、export、open、use、provide几个模块,这几个模块都是2个byte的长度加内容
  • 每个require长度固定,2个byte的name为字符串索引,2个byte的flag为字符串索引,2个byte的version
  • 每个export&open由2个byte的name为字符串索引,2个byte的flag,2个byte的exportTo&openTo的数量,每个exportTo&openTo有2个byte的字符串索引
  • 每个use长度固定,2个byte的name为字符串索引
  • 每个provides由2个byte的name为字符串索引,2个byte的providesWith数量,每个providesWith有2个byte的字符串索引
    在这里插入图片描述
  1. RUNTIME_INVISIBLE_ANNOTATIONS&RUNTIME_VISIBLE_ANNOTATIONS为2个byte的annotation数量,每个annotation有description为2个byte的字符串索引,及2个byte的ElementValuePair数量,每个ElementValuePair由2个byte的字符串索引的elementName及elementValue组成,elementValue内容中有1个byte为类型,除去类型之后
  • 如果类型为’e’,说明为ENUM,则内容为4个byte
  • 如果类型为’@’,说明为Annotation,内容会递归判断
  • 如果类型为’[’,说明为数组,内容则会判断其元素属性
  • 其它的类型内容都为2个byte在这里插入图片描述
  1. RUNTIME_VISIBLE_ANNOTATIONS&RUNTIME_INVISIBLE_TYPE_ANNOTATIONS跟RUNTIME_INVISIBLE_ANNOTATIONS类似,只是每个annotation在description前多了1个byte的targetType,根据targetType间隔不同byte数,又有1个byte的pathLength,及2*pathLength个byte的targetPath
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值