【在 JVM 眼中 .class 文件是什么样的?值得收藏】this_class(u2): 十进制值为5 , 指向常量池第5个常量 , 类型为CONSTANT_Class_info , 类为 TestClass
super_class(u2): 十进制值为5 , 指向第6个常量 , 类型为CONSTANT_Class_info , 类为 java/lang/Object
interface_count(u2): 实现接口数量 1 个
interface[0] :指向常量池第7个常量 , 类型为CONSTANT_Class_info , 接口名诶 java/io/Serializable
CONSTANT_Class_info 常量表结构如下// 伪代码
{
// 常量类型
u1 tag ;
// 指向常量池偏移量为name_index , 类型为CONSTANT_Utf8_info类型的索引 ,
//代表类或接口的权限定名
u2 name_index;
}
与之前所说常量池里在搭积木的说法一致 , 后面涉及到的常量池里的类型依然如此 。
访问标志使用标志位来表示 , 各个标志含义如表

文章插图
当前情况为 0x0001 | 0x0020 = 0x0021
05 attribute(属性表)
属性表比较特殊 , .Class文件、字段表、方法表等都可以携带自己的属性表集合 , 用来描述专有的场景 , 也因此将此表做前置说明 。
属性表的特点为:
规则较宽松 , 不要求严格的顺序、长度、内容
只要不与已有属性表重复 , 任何编译器都可以向属性表中写入自定义的属性信息 , JVM会忽略掉不认识的属性 。
属性表结构为// 伪代码
{
// 指向常量池类型为CONSTANT_Utf8_info的常量 , 代表属性名
u2 attribute_name_index ;
// 属性表info占用长度
u4 attribute_length;
// 这需要具体实现的结构 , 长度为attribute_length
Info info;
}
因此一个属性表的长度为 u2 + u4 + attribute_length 。Java与定义来很多属性表 , 文章检出涉及到的做后续说明 , 其它在实际需要时自行查阅

文章插图
字段表与方法表携带的属性表暂未涉及 , 当前节点涉及到类型为SourceFile的.Class携带的属性表 。

文章插图
class携带属性表示例
范围为 0x025A ~ 0x0262 共占 u2 + u4 + attibute_length = 8 字节 , SourceFile属性结构如下
伪代码
{
// 指向常量池类型为CONSTANT_Utf8_info的常量 , 代表属性名
u2 attribute_name_index ;
// 属性表内容占用长度
u4 attribute_length;
// 指向常量池类型为CONSTANT_Utf8_info的常量 , 代表源文件名
u2 sourcefile_index;
}
因此通过此SourceFile属性表 , 得知源文件名为TestClass.java
06 字段表
查阅.Class文件格式表 , 接口表之后 , 就是字段数量已经字段数量表

文章插图
字节码字段表
从 0x014D ~ 0x016E , 其中 0x014D ~ 0x014E 表示字段数 , 值为 0x0003 , 表示字段数为3 , 随便就是紧挨着的字段表 。字段表结构如下
// 伪代码
{
// 访问标志
u2 access_flags
// 指向常量池类型为CONSTANT_Utf8_info的常量 , 表示字段名
u2 name_index
// 指向常量池类型为CONSTANT_Utf8_info的常量 , 用描述符表示
// 字段类型
u2 descriptor_index
// 属性表数量
attributes_count
// 属性表内容
attribuite_info
}
字段表和.Class一样 , 能携带自己的属性表处理特殊场景 , attribuite_info是非必须的 。当attributes_count的值为0时 , 说明无需attribuite_info 。字段也拥有访问标志来对字段做进一步约束 。字段名则用name_index指向常量池的常量来表示 , 字段类型则用描述符来表示 , 比如 Int 表示为 I (忘了往前看基础知识) 。
当前例子定义的字段如下:
private int m = 123;
private static int x = 10;
private static final int y = 20;
定义了成员变量 m 和 类变量 x , y 。举例 y 来看

文章插图
位置为 0x015F ~ 0x016E , 其中:
访问标志:0x001A
推荐阅读
- 如何快速在mysql中生成大量Mock数据做性能测试?
- 茶烟自芬芳
- 5 分钟讲明白 JVM、Java 、Java对象模型
- 聊聊在AOP模式下的缓存方案
- 梦见家人反对我的感情 梦见家人反对我和男友在一起
- 茶乡 茶事 茶情
- 新鲜佛手柑的吃法
- 手臂变粗的原因是什么?
- 手冻伤后变粗怎么恢复
- 挡鼠板怎么安装 挡鼠板一般在哪里能买到
