实例分析Class字节码文件(一)

来源:互联网 发布:nginx apache php性能 编辑:程序博客网 时间:2024/06/06 00:54

一、小试牛刀

要分析的代码如下:

package com.demo6;    public class TestClass {        private int m;        public int inc(){            return m + 1;        }    }

Class字节码文件部分转化为16进制如下:

根据Class文件格式表:

转换几个:

编码(16进制) 说明 ca fe ba be 魔数 00 00 次版本号 00 33 主版本号 : JDK 1.7 00 16 常量池容量 :22-1 = 21 07 tag :CONSTANT_Class_info 00 02 name_index :指向常量池中的第二个常量 [name_index:必须指向的是一个CONSTANT_Utf8_info] 01 tag : CONSTANT_Utf8_info 00 13 length : 表示字符串长度是多少个字节(13) 63 6f 6d 2f 64 65 6d 6f 36 2f 54 65 73 bytes : com/demo6/TestClass


我们转换了两个常量,剩余19个使用JDK自带工具进行转化:

从上面的清单中,我们能看到常量池具有21个常量,从1开始计数。

第一个常量类型为CONSTANT_Class_info,并且指向第二个常量;
第二个常量类型为CONSTANT_Utf8_info,具体指com/demo6/TestClass;

与我们分析的一致。

二、访问标志

在常量池结束后,紧接着的两个字节代表访问标志(access_flags),这个标志用于识别一些类获接口层次的访问信息,包括:

① 这个Class是类还是接口
② 是否定义为public类型
③ 是否定义为abstract类型
④ 是否被声明为final等

access_flags一共有16位可以使用,当前只使用了8个,没有使用到的位一律为0.

具体标识如下:

以上面的代码为例:

是否为public类型 0x0001 √ 用了JDK1.2之后的编译器进行编译 0x0020 √ 其他 – ×


0x0001 | 0x0020 = 0x0021

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

紧接着访问标志后的就是类索引、父类索引和接口索引集合

类型 名称 说明 u2 类索引 类全限定名 u2 父类索引 父类全限定名 多个u2 接口索引集合 实现的所有接口的全限定名


类索引和父类索引引用两个u2类型的索引值表示,他们各自指向一个类型为CONSTANT_Class_info的类描述符常量,通过CONSTANT_Class_info找到CONSTANT_Utf8_info所表示的字符串。

对于接口索引集合,入口的第一项为u2类型的接口计数器(interfaces_count),表示实现接口的个数,如果为0,后面接口的索引表不再占用字节。

以上面的代码为例子:

类型 名称 值 u2 类索引 0x0001 u2 父类索引 0x0003 多个u2 接口索引集合 0x0000


① 类索引指向第一个常量;

② 父类索引指向第三个常量;

③ 接口索引集合为0,不占用任何字节;