<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    活到老,學(xué)到老

      BlogJava :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
      9 Posts :: 1 Stories :: 2 Comments :: 0 Trackbacks
    其實(shí)網(wǎng)上已經(jīng)有很多java Class文件的解析實(shí)例的文章,寫(xiě)這篇博客,只是為了自己仔仔細(xì)細(xì)的按照jvm spec看一邊,別無(wú)其他。

    先上class文件的格式。

    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 super_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[attributes_count];
        }

    其中,u2代表2個(gè)字節(jié)的無(wú)符號(hào)整數(shù)。u4代表4個(gè)字節(jié)的無(wú)符號(hào)整數(shù),其他如cp_infofield_info
    是一些結(jié)構(gòu)數(shù)據(jù),接下去會(huì)講。
    這次要解析的是一個(gè)非常簡(jiǎn)單的類:TJ.java,代碼如下:
    public class TJ
    {
        
    private final int f1 = 2
    ;

        
    public int m1(int
     i){
            
    return i+1
    ;
        }

        
    private void
     m2(){
        }
    }

    使用jdk1.6編譯,產(chǎn)生的二進(jìn)制類文件如下:

    CA FE BA BE 00 00 00 32 00 16 0A 00 04 00 12 09
    00 03 00 13 07 00 14 07 00 15 01 00 02 66 31 01
    00 01 49 01 00 0D 43 6F 6E 73 74 61 6E 74 56 61
    6C 
    75 65 03 00 00 00 02 01 00 06 3C 69 6E 69 74
    3E 
    01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00
    0F 4C 
    69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65
    01 00 02 6D 31 01 00 04 28 49 29 49 01 00 02 6D
    32 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00

    07 54 4A 2E 6A 61 76 61 0C 00 09 00 0A 0C 00 05
    00 06 01 00 02 54 4A 01 00 10 6A 61 76 61 2F 6C
    61 6E 67 2F 4F 62 6A 65 63 74 00 21 00 03 00 04

    00 00 00 01 00 12 00 05 00 06 00 01 00 07 00 00
    00 02 00 08 00 03 00 01 00 09 00 0A 00 01 00 0B
    00 00 00 26 00 02 00 01 00 00 00 0A 2A B7 00 01

    2A 
    05 B5 00 02 B1 00 00 00 01 00 0C 00 00 00 0A
    00 02 00 00 00 01 00 04 00 03 00 01 00 0D 00
     0E
    00 01 00 0B 00 00 00 1C 00 02 00 02 00 00 00 04

    1B 
    04 60 AC 00 00 00 01 00 0C 00 00 00 06 00 01
    00 00 00 06 00 02 00 0F 00 0A 00 01 00 0B 00 00
    00 19 00 00 00 01 00 00 00 01 B1 00 00 00 01 00
    0C 
    00 00 00 06 00 01 00 00 00 0B 00 01 00 10 00
    00 00 02 00 11
    下面對(duì)照上面的格式結(jié)構(gòu)一點(diǎn)點(diǎn)的解析。
    CA FE BA BE:頭四個(gè)字節(jié)是魔數(shù),表示這是java class文件。
    00 00:次版本為0。
    00 32:主版本0x32,表示jdk1.6編譯的。Jdk1.5為0x31,jdk1.4為0x30。
    00 16:常量池的入口(entry)數(shù)量。包括自己本身(這里很奇怪),所以接下來(lái)有21項(xiàng)的常量池入口。
    我會(huì)在每個(gè)常量池項(xiàng)的前面表上索引。常量池的第一個(gè)字節(jié)表示類型。具體類型對(duì)照表如下:
    Constant Type Value
    CONSTANT_Class 7
    CONSTANT_Fieldref 9
    CONSTANT_Methodref 10
    CONSTANT_InterfaceMethodref 11
    CONSTANT_String 8
    CONSTANT_Integer 3
    CONSTANT_Float 4
    CONSTANT_Long 5
    CONSTANT_Double 6
    CONSTANT_NameAndType 12
    CONSTANT_Utf8 1
    0A 00 04 00 12:【1】,第一個(gè)字節(jié)為10,所以是CONSTANT_Methodref,它的結(jié)構(gòu)如下:
    CONSTANT_Methodref_info {

    u1 tag;

    u2 class_index;

    u2 name_and_type_index;

    }

    所以,class_index=4,name_and_type_index=12,這兩個(gè)代表常量池第4項(xiàng)和第12項(xiàng)。

    09 00 03 00 13:【2】 這是一個(gè)CONSTANT_Fieldref,他的結(jié)構(gòu)和上面的類似class_index=3,name_and_type_index=13

    07 00 14:【3】這個(gè)是CONSTANT_Class,它的結(jié)構(gòu)如下:

    CONSTANT_Class_info {

        
    u1 tag;

        
    u2 name_index;

        }

    name_index為20,指向的是一個(gè)utf8的字節(jié)碼,即TJ,這個(gè)后面會(huì)看到。

    07 00 15: 【4】 也是一個(gè)CONSTANT_Class,name_index為21,即java/lang/Object

    01 00 02 66 31: 【5】CONSTANT_Utf8,結(jié)構(gòu)如下:

    CONSTANT_Utf8_info {

    u1 tag;

    u2 length;

    u1 bytes[length];

    }

    最后兩個(gè)字節(jié)代表字符串“f1”的utf-8字節(jié)碼。

    01 00 01 49:【6】字符串I

    01 00 0D 43 6F 6E 73 74 61 6E 74 56 61 6C 75 65 :【7】字符串ConstantValue

    03 00 00 00 02:【8】CONSTANT_Integer,整數(shù)值2

    01 00 06 3C 69 6E 69 74 3E:【9】字符串<init>

    01 00 03 28 29 56:【10】字符串()V

    01 00 04 43 6F 64 65:【11】字符串code

    01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65:【12】字符串LineNumberTable

    01 00 02 6D 31:【13】字符串m1

    01 00 04 28 49 29 49 :【14】字符串(I)I,表示一個(gè)整數(shù)參數(shù)且返回整數(shù)的方法。

    01 00 02 6D 32 :【15】字符串m2

    01 00 0A 53 6F 75 72 63 65 46 69 6C 65 :【16】字符串SourceFile

    01 00 07 54 4A 2E 6A 61 76 61:【17】字符串TJ.java

    0C 00 09 00 0A:【18】CONSTANT_NameAndType,結(jié)構(gòu)如下:

    CONSTANT_NameAndType_info {

    u1 tag;

    u2 name_index;

    u2 descriptor_index;

    }
    name_index=9,代表方法<init>,descriptor_index=10,()V,代表無(wú)參且返回void的方法。


    0C 00 05 00 06:【19】結(jié)構(gòu)同上,name_index=5,即f1,descriptor_index=6,即整數(shù)。

    01 00 02 54 4A :【20】字符串TJ

    01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74:【21】字符串java/lang/Object

    到此,常量池結(jié)束。
    00 21:類的描述符為public。
    00 03 :this class為常量池第三個(gè),TJ,即這個(gè)類的名字為TJ
    00 04:super class為常量池第四個(gè),java/lang/Object,即它的超類為java.lang.Object
    00 00:接口個(gè)數(shù)0。
    00 01:field數(shù)量1。
    00 12 00 05 00 06 00 01 00 07 00 00 00 02 00 08:field的結(jié)構(gòu)如下
    field_info {
         u2 access_flags;
         u2 name_index;
         u2 descriptor_index;
         u2 attributes_count;
         attribute_info attributes[attributes_count];
        }
    access_flags為00 12,代表ACC_PRIVATE+ ACC_FINAL

    name_index:常量池索引為5的入口,即f1,即類成員的名字為f1
    descriptor_index:I,代表integer。
     attributes_count:1個(gè)。
    attribute_info:
    attribute_info {
         u2 attribute_name_index;
         u4 attribute_length;
         u1 info[attribute_length];
    }

    attribute_name_index:7,即ConstantValue,結(jié)構(gòu)如下
    ConstantValue_attribute {
         u2 attribute_name_index;
         u4 attribute_length;
         u2 constantvalue_index;
        }
    attribute_length:2
    constantvalue_index:2
    ----------------------------------------下面開(kāi)始方法

    00 03:3個(gè)方法。
    method_info {
         u2 access_flags;
         u2 name_index;
         u2 descriptor_index;
         u2 attributes_count;
         attribute_info attributes[attributes_count];
        }
    --------------------------------------------第一個(gè)方法<init>,這個(gè)是編譯器產(chǎn)生的生成實(shí)例的初始化方法。
    access_flags:public
    name_index:00 09,<init>
    descriptor_index:00 0A,()V表示無(wú)參數(shù),返回void
    attributes_count :00 01,1個(gè)
    attribute_name_index :00 0B ,code
    attribute_length:38個(gè)
    Code_attribute {
         u2 attribute_name_index;
         u4 attribute_length;
         u2 max_stack;
         u2 max_locals;
         u4 code_length;
         u1 code[code_length];
         u2 exception_table_length;
         {     u2 start_pc;
                u2 end_pc;
                u2  handler_pc;
                u2  catch_type;
         } exception_table[exception_table_length];
         u2 attributes_count;
         attribute_info attributes[attributes_count];
        }
    max_stack: 00 02
    max_locals: 00 01
    code_length: 00 00 00 0A,10
    code: 2A B7 00 01 2A 05 B5 00 02 B1,指令
    exception table length:00 00
    attributes_count:1
    attribute_name_index:00 0C,LineNumberTable
    LineNumberTable_attribute {
         u2 attribute_name_index;
         u4 attribute_length;
         u2 line_number_table_length;
         {  u2 start_pc;     
            u2 line_number;     
         } line_number_table[line_number_table_length];
        }
    attribute_length:10
    line_number_table_length:2
    start_pc:00 00
    line_number:00 01
    tart_pc:00 04
    line_number:00 03
    到此第一個(gè)方法結(jié)束。
    ----------------------------------------------------------------------第二個(gè)方法開(kāi)始
    access_flags00 01public
    name_index:00 0D,m1
    desc_index:00 0E,(I)I,有一個(gè)整數(shù)參數(shù),返回一個(gè)整數(shù)。
    00 01:一個(gè)attr
    00 0B:code
    00 00 00 1C:attr_length:28
    Code_atrr:28個(gè)字節(jié),不分析了和上面的方法相同。

    ----------------------------------------------------------------------第三個(gè)方法
    00 02:private
    00 0F:m2
    00 0A: ()V,無(wú)參,返回void
    00 01:一個(gè)attr
    00 0B:code
    00 00 00 19:attr_length  25
    接下去的25個(gè)字節(jié)是Code_atrr,同樣不分析了。
    ------------------------------------------------------------------
    00 01:1個(gè)類的attr
    00 10:SourceFile
    00 00 00 02:len=2
    00 11:17,TJ.java

    posted on 2010-02-22 19:30 simon.shen 閱讀(1409) 評(píng)論(0)  編輯  收藏 所屬分類: Jvm,Java Core

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 免费高清在线爱做视频| 国产成人亚洲综合网站不卡| 日韩伦理片电影在线免费观看| 小日子的在线观看免费| 日本高清不卡中文字幕免费| 亚洲一级片在线播放| 亚洲AV电影院在线观看| 亚洲人AV永久一区二区三区久久| 永久中文字幕免费视频网站| 69视频在线观看免费| 成全在线观看免费观看大全| 黄网站色成年片大免费高清| 亚洲中文字幕无码中文| 亚洲黄色在线观看视频| 久久亚洲AV午夜福利精品一区| 久久亚洲国产精品五月天婷| 国产大片91精品免费看3| 影音先锋在线免费观看| 三年片在线观看免费大全| 69视频在线观看免费| 1000部夫妻午夜免费| 99免费在线观看视频| 国产情侣久久久久aⅴ免费| 国产男女爽爽爽免费视频| 免费国产va在线观看| 国产精品亚洲综合一区在线观看 | 久久亚洲AV成人无码国产 | 午夜不卡AV免费| 国产亚洲精品2021自在线| 婷婷国产偷v国产偷v亚洲| 亚洲风情亚Aⅴ在线发布| 最新亚洲精品国偷自产在线| 国产成人精品日本亚洲直接 | 69天堂人成无码麻豆免费视频| 最近免费中文字幕mv在线电影| 毛片无码免费无码播放| 91精品免费观看| 四虎成年永久免费网站| 免费黄色网址网站| 18禁成年无码免费网站无遮挡 | 亚洲色大成网站www|