一把小刀,直插 class 文件的小心脏(3)

简介: 一把小刀,直插 class 文件的小心脏

接下来是 CONSTANT_Fieldref_info 、CONSTANT_Methodref_info 和 CONSTANT_InterfaceMethodref_info,它们三个的结构比较类似,可以通过下面的伪代码来表示。


CONSTANT_*ref_info {

 u1 tag;

 u2 class_index;

 u2 name_and_type_index;

}



学过 C 语言的符号表(Symbol Table)的话,对这段伪代码并不会陌生。


tag 为标识符,Fieldref 的为 9,也就是十六进制的 0x09;Methodref 的为 10,也就是十六进制的 0x0a;InterfaceMethodref 的为 11, 也就是十六进制的 0x0b。

class_index 为 CONSTANT_Class_info 的常量池索引,表示字段 | 方法 | 接口方法所在的类信息。

name_and_type_index 为 CONSTANT_NameAndType_info 的常量池索引,拿 Fieldref 来说,表示字段名和字段类型;拿 Methodref 来说,表示方法名、方法的参数和返回值类型;拿 InterfaceMethodref 来说,表示接口方法名、接口方法的参数和返回值类型。

还有 CONSTANT_MethodHandle_info 、CONSTANT_MethodType_info 和 CONSTANT_InvokeDynamic_info,我就不再一一说明了,大家也可以拿把小刀去试一试。


啊,class 文件中最复杂的常量池部分就算是解剖完了,真不容易!


04、访问标记


紧跟着常量池之后的区域就是访问标记(Access flags),这个标记用于识别类或接口的访问信息,比如说到底是 class 还是 interface?是 public 吗?是 abstract 抽象类吗?是 final 类吗?等等。总共有 16 个标记位可供使用,但常用的只有其中 7 个。


image.png


来看一个简单的枚举代码。


public enum Color {

   RED,GREEN,BLUE;

}



通过 jclasslib 可以看到访问标记的信息有 0x4031 [public final enum]。


image.png


对应 class 文件中的位置如下图所示。


image.png


05、this_class、super_class、interfaces


这三部分用来确定类的继承关系,this_class 为当前类的索引,super_class 为父类的索引,interfaces 为接口。


来看下面这段简单的代码,没有接口,默认继承 Object 类。


class Hello {

   public static void main(String[] args) {

     

   }

}


通过 jclasslib 可以看到类的继承关系。


this_class 指向常量池中索引为 2 的 CONSTANT_Class_info。

super_class 指向常量池中索引为 3 的 CONSTANT_Class_info。

由于没有接口,所以 interfaces 的信息为空。

对应 class 文件中的位置如下图所示。


image.png


06、字段表


一个类中定义的字段会被存储在字段表(fields)中,包括静态的和非静态的。


来看这样一段代码。


public class FieldsTest {

   private String name;

}


字段只有一个,修饰符为 private,类型为 String,字段名为 name。可以用下面的伪代码来表示 field 的结构。


field_info {

 u2 access_flag;

 u2 name_index;

 u2 description_index;

}


access_flag 为字段的访问标记,比如说是不是 public | private | protected,是不是 static,是不是 final 等。

name_index 为字段名的索引,指向常量池中的 CONSTANT_Utf8_info, 比如说上例中的值就为 name。

description_index 为字段的描述类型索引,也指向常量池中的 CONSTANT_Utf8_info,针对不同的数据类型,会有不同规则的描述信息。

1)对于基本数据类型来说,使用一个字符来表示,比如说 I 对应的是 int,B 对应的是 byte。


2)对于引用数据类型来说,使用 L***; 的方式来表示,L 开头,; 结束,比如字符串类型为 Ljava/lang/String;。


3)对于数组来说,会用一个前置的 [ 来表示,比如说字符串数组为 [Ljava/lang/String;。


对应到 class 文件中的位置如下图所示。


image.png


07、方法表


方法表和字段表类似,区别是用来存储方法的信息,包括方法名,方法的参数,方法的签名。


就拿 main 方法来说吧。


public class MethodsTest {

   public static void main(String[] args) {

     

   }

}


先用 jclasslib 看一下大概的信息。


image.png


访问标记是 public static 的。

方法名为 main。

方法的参数为字符串数组;返回类型为 Void。

对应到 class 文件中的位置如下图所示。


image.png



相关文章
|
5月前
【每日一题Day313】LC2511最多可以摧毁的敌人城堡数目 | 模拟
【每日一题Day313】LC2511最多可以摧毁的敌人城堡数目 | 模拟
37 0
|
2月前
|
网络安全 数据安全/隐私保护
网工救急秘籍:四种恢复 console 口密码的神奇方法背后藏着怎样的玄机?
【8月更文挑战第19天】作为网络工程师,遇到设备console口密码遗忘实属头疼。这里有四大救急法助你迅速解决:一是调整配置寄存器值让设备忽略原有配置;二是利用无密码的备份配置文件恢复;三是重置设备至出厂设置(慎用);四是通过硬件短接清除密码(需谨慎)。这些方法曾在关键时候帮助我解决了客户的网络危机,避免业务中断。记得恢复后要设置强密码并妥善保管,确保网络安全稳定。
19 0
用试题这把“剑“帮你破除指针与数组之间的那些猫腻
用试题这把“剑“帮你破除指针与数组之间的那些猫腻
59 0
|
机器学习/深度学习 存储 人工智能
用视频插帧开一个流体力学分析的外挂
阿里云提供的线上AI能力在处理视觉信息方面已经有较为成熟和通用的产品,其中视频插帧可以用于现有超高速相机增强,用于粒子测量PIV、BOS背景纹影等领域。本文为视觉流体力学分析预处理中间件的开发思路、技术架构设计和开发实战中参数的设置介绍,对一些数字影像的基础概念和阿里云视觉人工智能的API细节进行了分析。
410 0
用视频插帧开一个流体力学分析的外挂
C++语法基础(七)——可恶的指针(三)
C++语法基础(七)——可恶的指针(三)
C++语法基础(七)——可恶的指针(三)
|
存储 C++ 索引
C++语法基础(七)——可恶的指针(二)
C++语法基础(七)——可恶的指针(二)
C++语法基础(七)——可恶的指针(二)
|
存储 C++
C++语法基础(七)——可恶的指针(一)
C++语法基础(七)——可恶的指针(一)
C++语法基础(七)——可恶的指针(一)
|
算法 安全 C++
科学家小蓝来到了一个荒岛,准备对这个荒岛进行探测考察。 小蓝使用了一个超声定位设备来对自己进行定位。为了使用这个设备,小蓝需要在不同的点分别安装一个固定的发射器和一个固定的接收器。小蓝手中还有一个移
科学家小蓝来到了一个荒岛,准备对这个荒岛进行探测考察。 小蓝使用了一个超声定位设备来对自己进行定位。为了使用这个设备,小蓝需要在不同的点分别安装一个固定的发射器和一个固定的接收器。小蓝手中还有一个移
273 0
科学家小蓝来到了一个荒岛,准备对这个荒岛进行探测考察。 小蓝使用了一个超声定位设备来对自己进行定位。为了使用这个设备,小蓝需要在不同的点分别安装一个固定的发射器和一个固定的接收器。小蓝手中还有一个移
|
数据库
买手机数据线特别要注意的地方
买手机数据线特别要注意的地方
118 0