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

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

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

    上善若水
    In general the OO style is to use a lot of little objects with a lot of little methods that give us a lot of plug points for overriding and variation. To do is to be -Nietzsche, To bei is to do -Kant, Do be do be do -Sinatra
    posts - 146,comments - 147,trackbacks - 0

    小介:去年在讀《深入解析JVM》的時候?qū)懙模浀卯?dāng)時還想著用自己的代碼解析字節(jié)碼的,最后只完成了一部分。現(xiàn)在都不知道還有沒有保留著,貌似Apache有現(xiàn)成的BCEL工程可以做這件事。當(dāng)時也只是為了學(xué)習(xí)。這份資料主要參考《深入解析JVM》和《Java虛擬機規(guī)范》貌似是1.2版本的,整理出來的。里面包含了一些自己的理解和用實際代碼的測試。有興趣的童鞋可以研究研究。嘿嘿。要有錯誤也希望能為小弟指點出來,感激不盡。:)

    1.
    總體格式

    Class File format

    type

    descriptor

    remark

    u4

    magic

    0xCAFEBABE

    u2

    minor_version

     

    u2

    major_version

     

    u2

    constant_pool_count

     

    cp_info

    constant_pool[cosntant_pool_count – 1]

    index 0 is invalid

    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]

     

     

    2.     格式詳解

    2.1  magic

    magic被稱為“魔數(shù)”,用來標(biāo)識.class文件的開頭。所有合法的.class字節(jié)碼都應(yīng)該是該數(shù)開頭,占4個字節(jié)。

    2.2  major_version.minor_version

    major_version.minor_version合在一起形成當(dāng)前.class文件的版本號,該版本號一般由編譯器產(chǎn)生,并且由sun定義。如59.0。它們一起占4個字節(jié)。

    2.3  constant_pool

    Java字節(jié)碼中,有一個常量池,用來存放不同類型的常量。由于Java設(shè)計的目的之一就是字節(jié)碼需要經(jīng)網(wǎng)絡(luò)傳輸?shù)模蚨止?jié)碼需要比較緊湊,以減少網(wǎng)絡(luò)傳輸?shù)牧髁亢蜁r間。常量池的存在則可以讓一些相同類型的值通過索引的方式從常量池中找到,而不是在不同地方有不同拷貝,縮減了字節(jié)碼的大小。

    每個常量池中的項是通過cp_info的類型來表示的,它的格式如下:

    cp_info format

    type

    descriptor

    remark

    u1

    tag

     

    u1

    info[]

     

    這里tag用來表示當(dāng)前常量池不同類型的項。info中存放常量池項中存放的數(shù)據(jù)。

    tag中表示的數(shù)據(jù)類型:

    CONSTANT_Class_info                                  7)、

    CONSTANT_Integer_info                              3)、

    CONSTANT_Long_info                                   5)、

    CONSTANT_Float_info                                  4)、

    CONSTANT_Double_info                              6)、

    CONSTANT_String_info                                 8)、

    CONSTANT_Fieldref_info                              9)、

    CONSTANT_Methodref_info                       10)、

    CONSTANT_InterfaceMethodref_info      11)、

    CONSTANT_NameAndType_info                12)、

    CONSTANT_Utf8_info                                   1)、

    注:在Java字節(jié)碼中,所有booleanbytecharshort類型都是用int類型存放,因而在常量池中沒有和它們對應(yīng)的項。

    2.3.1    CONSTANT_Class_info

    用于記錄類或接口名(used to represent a class or an interface

    CONSTANT_Class_info format

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Class (7)

    u2

    name_index

    constant_pool中的索引,CONSTANT_Utf8_info類型。表示類或接口名。

    注:在Java字節(jié)碼中,類和接口名不同于源碼中的名字,詳見附件A.

     

    2.3.2    CONSTANT_Integer_info

    用于記錄int類型的常量值(represent 4-byte numeric (int) constants:

    CONSTANT_Integer_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Integer (3)

    u4

    bytes

    整型常量值

     

    2.3.3    CONSTANT_Long_info

    用于記錄long類型的常量值(represent 8-byte numeric (long) constants:

    CONSTANT_Long_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Long (5)

    u4

    high_bytes

    長整型的高四位值

    u4

    low_bytes

    長整型的低四位值

     

    2.3.4    CONSTANT_Float_info

    用于記錄float類型的常量值(represent 4-byte numeric (float) constants:

    CONSTANT_Float_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Float(4)

    u4

    bytes

    單精度浮點型常量值

    幾個特殊值:0x7f800000 => Float.POSITIVE_INFINITY0xff800000 => Float.NEGATIVE_INFINITY

                    0x7f800001 to 0x7fffffff => Float.NaN0xff800001 to 0xffffffff => Float.NaN

     

    2.3.5    CONSTANT_Double_info

    用于記錄double類型的常量值(represent 8-byte numeric (double) constants:

    CONSTANT_Double_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Double(6)

    u4

    high_bytes

    雙精度浮點的高四位值

    u4

    low_bytes

    雙精度浮點的低四位值

    幾個特殊值:0x7ff0000000000000L => Double.POSITIVE_INFINITY

    0xfff0000000000000L => Double.NEGATIVE_INFINITY

    0x7ff0000000000001L to 0x7fffffffffffffffL => Double.NaN

    0xfff0000000000001L to 0xffffffffffffffffL => Double.NaN

     

    2.3.6    CONSTANT_String_info

    用于記錄常量字符串的值(represent constant objects of the type String:

    CONSTANT_String_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_String(8)

    u2

    string_index

    constant_pool中的索引,CONSTANT_Utf8_info類型。表示String類型值。

     

    2.3.7    CONSTANT_Fieldref_info

    用于記錄字段信息(包括類或接口中定義的字段以及代碼中使用到的字段)。

    CONSTANT_Fieldref_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Fieldref(9)

    u2

    class_index

    constant_pool中的索引,CONSTANT_Class_info類型。記錄定義該字段的類或接口。

    u2

    name_and_type_index

    constant_pool中的索引,CONSTANT_NameAndType_info類型。指定類或接口中的字段名(name)和字段描述符(descriptor)。

     

    2.3.8    CONSTANT_Methodref_info

    用于記錄方法信息(包括類中定義的方法以及代碼中使用到的方法)。

    CONSTANT_Methodref_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Methodref(10)

    u2

    class_index

    constant_pool中的索引,CONSTANT_Class_info類型。記錄定義該方法的類。

    u2

    name_and_type_index

    constant_pool中的索引,CONSTANT_NameAndType_info類型。指定類中扽方法名(name)和方法描述符(descriptor)。

     

    2.3.9    CONSTANT_InterfaceMethodref_info

    用于記錄接口中的方法信息(包括接口中定義的方法以及代碼中使用到的方法)。

    CONSTANT_InterfaceMethodref_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_InterfaceMethodref(11)

    u2

    class_index

    constant_pool中的索引,CONSTANT_Class_info類型。記錄定義該方法的接口。

    u2

    name_and_type_index

    constant_pool中的索引,CONSTANT_NameAndType_info類型。指定接口中的方法名(name)和方法描述符(descriptor)。

     

    2.3.10    CONSTANT_NameAndType_info

    記錄方法或字段的名稱(name)和描述符(descriptor)represent a field or method, without indicating which class or interface type it belongs to:)。

    CONSTANT_NameAndType_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_NameAndType (12)

    u2

    name_index

    constant_pool中的索引,CONSTANT_Utf8_info類型。指定字段或方法的名稱。

    u2

    descriptor_index

    constant_pool中的索引,CONSTANT_utf8_info類型。指定字段或方法的描述符(見附錄C

     

    2.3.11    CONSTANT_Utf8_info

    記錄字符串的值(represent constant string values. String content is encoded in modified UTF-8.

    modifie

    d UTF-8 refer to :

    http://download.ora

    cle.com/javase/1.4.2/docs/api/java/io/DataInputStream.html

    CONSTANT_Utf8_info

    type

    descriptor

    remark

    u1

    tag

    CONSTANT_Utf8 (1)

    u2

    length

    bytes所代表

    的字符串的長度

    u1

    bytes[length]

    字符串的byte數(shù)據(jù),可以通過DataInputStream中的readUtf()方法(實例方法或靜態(tài)方法讀取該二進制的字符串的值。)

     

    2.4  access_flags

    指定類或接口的訪問權(quán)限。

    類或接口的訪問權(quán)限

    Flag Name

    Value

    Remarks

    ACC_PUBLIC

    0x0001

    pubilc,包外可訪問。

    ACC_FINAL

    0x0010

    final,不能有子類。

    ACC_SUPER

    0x0020

    用于兼容早期編譯器,新編譯器都設(shè)置該標(biāo)記,以在使用 invokespecial指令時對子類方法做特定處理。

    ACC_INTERFACE

    0x0200

    接口,同時需要設(shè)置:ACC_ABSTRACT。不可同時設(shè)置:ACC_FINALACC_SUPERACC_ENUM

    ACC_ABSTRACT

    0x0400

    抽象類,無法實例化。不可和ACC_FINAL同時設(shè)置。

    ACC_SYNTHETIC

    0x1000

    synthetic,由編譯器產(chǎn)生,不存在于源代碼中。

    ACC_ANNOTATION

    0x2000

    注解類型(annotation),需同時設(shè)置:ACC_INTERFACEACC_ABSTRACT

    ACC_ENUM

    0x4000

    枚舉類型

     

    2.5  this_class

    this_class是指向constant pool的索引值,該值必須是CONSTANT_Class_info類型,指定當(dāng)前字節(jié)碼定義的類或接口。

     

    2.6  super_class

    super_class是指向constant pool的索引值,該值必須是CONSTANT_Class_info類型,指定當(dāng)前字節(jié)碼定義的類或接口的直接父類。只有Object類才沒有直接父類,此時該索引值為0。并且父類不能是final類型。接口的父類都是Object類。

     

    2.7  interfaces

    interfaces數(shù)組記錄所有當(dāng)前類或接口直接實現(xiàn)的接口。interfaces數(shù)組中的每項值都是一個指向constant pool的索引值,這些值必須是CONSTANT_Class_info類型。數(shù)組中接口的順序和源代碼中接口定義的順序相同。

     

    2.8  fields

    fields數(shù)組記錄了類或接口中的所有字段,包括實例字段和靜態(tài)字段,但不包含父類或父接口中定義的字段。fields數(shù)組中每項都是field_info類型值,它描述了字段的詳細信息,如名稱、描述符、字段中的attribute等。

    field_info

    type

    descriptor

    remark

    u2

    access_flags

    記錄字段的訪問權(quán)限。見2.8.1

    u2

    name_index

    constant_pool中的索引,CONSTANT_Utf8_info類型。指定字段的名稱。

    u2

    descriptor_index

    constant_pool中的索引,CONSTANT_Utf8_info類型,指定字段的描述符(見附錄C)。

    u2

    attributes_count

    attributes包含的項目數(shù)。

    attribute_info

    attributes[attributes_count]

    字段中包含的Attribute集合。見2.8.2-2.8.7

    注:fields中的項目和CONSTANT_Fieldref_info中的項目部分信息是相同的,他們主要的區(qū)別是CONSTANT_Fieldref_info中的項目不僅包含了類或接口中定義的字段,還包括在字節(jié)碼中使用到的字段信息。不過這里很奇怪,為什么field_info結(jié)構(gòu)中不把name_indexdescriptor_index合并成fieldref_index,這樣的class文件不是更加緊湊嗎??不知道這是sun因為某些原因故意這樣設(shè)計還是這是他們的失誤??

     

    2.8.1    字段訪問權(quán)限

    字段的訪問權(quán)限

    Flag Name

    Value

    Remarks

    ACC_PUBLIC

    0x0001

    pubilc,包外可訪問。

    ACC_PRIVATE

    0x0002

    private,只可在類內(nèi)訪問。

    ACC_PROTECTED

    0x0004

    protected,類內(nèi)和子類中可訪問。

    ACC_STATIC

    0x0008

    static,靜態(tài)。

    ACC_FINAL

    0x0010

    final,常量。

    ACC_VOILATIE

    0x0040

    volatile,直接讀寫內(nèi)存,不可被緩存。不可和ACC_FINAL一起使用。

    ACC_TRANSIENT

    0x0080

    transient,在序列化中被忽略的字段。

    ACC_SYNTHETIC

    0x1000

    synthetic,由編譯器產(chǎn)生,不存在于源代碼中。

    ACC_ENUM

    0x4000

    enum,枚舉類型字段

    注:接口中的字段必須同時設(shè)置:ACC_PUBLICACC_STATICACC_FINAL

     

    2.8.2    ConstantValue Attribute JVM識別)

    ConstantValue Attribute

    type

    descriptor

    remark

    u2

    attribute_name_index

    constant_pool中的索引,CONSTANT_Utf8_info類型。指定Attribute的名稱(“ConstantValue”)

    u4

    attribute_length

    Attribute內(nèi)容的字節(jié)長度(固定值:2

    u2

    constant_value_index

    constant_pool中的索引,

    CONSTANT_Integer_infointbooleancharshortbyte)、

    CONSTANT_Float_infofloat)、

    Constant_Double_infodouble)、

    CONSTANT_Long_infolong

    CONSTANT_String_infoString)類型

    每個常量字段(final,靜態(tài)常量或?qū)嵗A浚┒及星覂H有一個ConstantValue AttributeConstantValue Attribute結(jié)構(gòu)用于存儲一個字段的常量值。

     

    對一個靜態(tài)常量字段,該常量值會在類或接口被初始化之前,由JVM負責(zé)賦給他們,即它在任何靜態(tài)字段之前被賦值。

     

    對一個非靜態(tài)常量字段,該值會被虛擬機忽略,它的賦值由生成的實例初始化函數(shù)(<init>)實現(xiàn)。如類:

    class A {

        public static final int fa = 10;

        public final int fa2 = 30;

        private static int sa = 20;

        static {

           sa = 30;

        }

    }

    生成的字節(jié)碼如下:

    // Compiled from Test.java (version 1.6 : 50.0, super bit)

    class org.levin.insidejvm.miscs.staticinit.A {

     public static final int fa = 10;

     public final int fa2 = 30;

     private static int sa;

      static {};

         0 bipush 20

         2 putstatic org.levin.insidejvm.miscs.staticinit.A.sa : int [16]

         5 bipush 30

         7 putstatic org.levin.insidejvm.miscs.staticinit.A.sa : int [16]

        10 return

     public A();

         0 aload_0 [this]

         1 invokespecial java.lang.Object() [21]

         4 aload_0 [this]

         5 bipush 30

         7 putfield org.levin.insidejvm.miscs.staticinit.A.fa2 : int [23]

    10 return

     

    2.8.3    Synthetic Attribute

    參考2.11.1

    2.8.4    Signature Attribute

    參考2.11.2

    2.8.5    Deprecated Attribute

    參考2.11.3

    2.8.6    RuntimeVisibleAnnotations Attribute

    參考2.11.4

    2.8.7    RuntimeInvisibleAnnotations Attribute

    參考2.11.5

                                                                                                                            于2010-12-19

    posted on 2011-09-05 23:24 DLevin 閱讀(20012) 評論(3)  編輯  收藏 所屬分類: 深入JVM

    FeedBack:
    # re: Java字節(jié)碼(.class文件)格式詳解(一)
    2011-09-05 23:51 | 步步為營
    很細,很深入  回復(fù)  更多評論
      
    # re: Java字節(jié)碼(.class文件)格式詳解(一)[未登錄]
    2011-09-06 07:15 | feenn
    不錯,接著跟蹤  回復(fù)  更多評論
      
    # re: Java字節(jié)碼(.class文件)格式詳解(一)
    2011-09-06 09:55 | Red Wolf
    不錯,也研究過段時間  回復(fù)  更多評論
      
    主站蜘蛛池模板: 九九全国免费视频| 日韩精品无码免费专区网站| 成人爽a毛片免费| 国产情侣激情在线视频免费看| 全黄A免费一级毛片| 日本一卡精品视频免费| 日韩在线视频免费看| 久久精品国产亚洲av成人| 亚洲精品永久在线观看| 黄桃AV无码免费一区二区三区| 日本一区二区三区免费高清| 亚洲色成人网站WWW永久| 亚洲中文字幕久久精品无码VA| 成人A毛片免费观看网站| 24小时日本在线www免费的| 亚洲熟妇av一区二区三区漫画| 亚洲激情视频图片| 免费看成人AA片无码视频吃奶| 在线a人片天堂免费观看高清| 久久久久久久综合日本亚洲| 亚洲精品国产av成拍色拍| a在线视频免费观看| 国产精品无码一二区免费| 91亚洲va在线天线va天堂va国产 | 国产成人免费片在线观看| 亚洲国产精品热久久| 免费国产黄网站在线观看动图| 一色屋成人免费精品网站 | 亚洲国产成人片在线观看| 大桥未久亚洲无av码在线| 久草视频免费在线观看| 大学生a级毛片免费观看| 久久国产亚洲电影天堂| 成人免费夜片在线观看| 拍拍拍又黄又爽无挡视频免费| 亚洲va无码专区国产乱码| 人与动性xxxxx免费| 青青草国产免费久久久91| 亚洲高清视频免费| 国产免费网站看v片在线| 亚洲精品A在线观看|