Java學習之路

          墻上蘆葦,頭重腳輕根底淺;山間竹筍,嘴尖皮厚腹中空。

          常用鏈接

          統計

          最新評論

          2009年3月23日 #

          讀書筆記:java的class文件格式分析(一)

          閱讀Java Virtual Machine Specification中的第四章,理解Java的class文件格式。

          class文件由8位的字節流組成。

          The ClassFile Structure

          ClassFile{

          u4 magic;

          u2 minor_version;

          u2 major_version;

          u2 constant_pool_count;

          cp_info constant_pool[constant_pool_count-1];

          u2 access_flags;

          u2 this_class;

          u2 interfaces_count;

          u2 interfaces[interfaces_count];

          u2 fields_count;

          field_info fields[fields_count];

          u2 methods_count;

          method_info methods[methods_count];

          u2 attributes_count;

          attribute_info attributes[attrributes_count];

          }

          說明:u2表示無符號2字節量,u4表示無符號4字節量。

          各字段的說明:

          magic

          一般二進制文件中都有magic number這一項,這個數說明該文件是一個class文件,它的值是0xcAFEBABE。

          minor_version,major_version

          class文件的版本號。

          constant_pool_count

          常量池表中項目數加1得到。從后面的cp_info constant_pool[constant_pool_count-1];也容易理解這個值的意思。

          cp_info constant_pool[]

          存儲該class文件中使用到的常量信息。

          access_flag

          說明該class文件的訪問權限和相關屬性,通過位掩碼來設定。

          Flag Name 解釋
          ACC_PUBLIC 0x0001 public
          ACC_FINAL 0x0010 final
          ACC_SUPER 0x0020 跟調用invokespecial指令時的處理有關
          ACC_INTERFACE 0x0200 這是個接口
          ACC_ABSTRACT 0x0400 abastract
          ACC_SYNTHETIC 0x1000 沒有在源代碼中出現,該類是編譯器生成的
          ACC_ANNOTATION 0x2000 注解類型
          ACC_ENUM 0x4000 枚舉類型

           

          這些屬性都很容易理解,比如我們定義一個類public final Test{},則Test.class的access_flag中,ACC_PUBLIC和ACC_FINAL是置位的,而ACC_INTERFACE一項肯定是0。很多類似的組合規則倒是容易自己總結出來,比如如果ACC_INTERFACE置位了,那肯定ACC_ABSTRACT也是置位的,因為接口肯定是抽象的;如果ACC_ANNOTATION置位了,那ACC_ANNOTATION肯定同時置位,等等,諸如此類。

          畫一個具體的位示意圖表示:

          image

          this_class

          一個下標,指向常量池表中代表當前類的Constant_Class_info。

          super_class

          為0,或者為一個下標,指向常量池中代表其父類的Constant_Class_info。如果這個值為0,那么當前類肯定是Object類。如果當前類是一個接口,該下標指向的是Object類的描述信息。

          interface_count

          該類實現的接口數,或者該接口實現的超接口數。

          interfaces[]

          具體的接口信息,每一項都是常量池表中的一個下標,指向表示接口的Constant_Class_info。

          后面幾個依次是字段(field),方法(methods)和屬性的描述,不再贅述,

           

          下面具體的分析一個class文件。源文件很簡單:

          public class Test{
          public static void main(String[] args){
          System.out.println("Hello World!");
          }
          }

           

          編譯,得到Test.class文件,使用WinHex打開。

          image

          前4個字節是magic部分,內容為0xCAFEBABE;隨后的4個字節是class文件的版本號,這里主版本號是0x0032,也就是50,這是使用jdk1.6編譯出的class文件。再后面的2個字節是常量池表的大小信息,0x001D,也就是29,說明常量池表中一共有28項。為了方便觀察,可以使用javap -verbose Test得到的結果和當前的二進制文件進行對比。

          入門到此,以后繼續。

          posted @ 2009-03-23 12:20 Zang XT 閱讀(133) | 評論 (0)編輯 收藏

          主站蜘蛛池模板: 满城县| 榆社县| 陇川县| 沭阳县| 雷波县| 吉林市| 西充县| 蕲春县| 乌拉特中旗| 唐山市| 禹州市| 江华| 唐海县| 泰顺县| 林西县| 东山县| 临泉县| 绥芬河市| 灵山县| 旌德县| 津市市| 青岛市| 兴化市| 镇宁| 张家界市| 全椒县| 迁安市| 开封县| 镶黄旗| 余庆县| 鄂托克前旗| 山阴县| 六枝特区| 广德县| 竹溪县| 福海县| 故城县| 鞍山市| 安陆市| 化州市| 长沙县|