上善若水
          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
          <2011年9月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          常用鏈接

          留言簿(4)

          隨筆分類(157)

          隨筆檔案(125)

          收藏夾(13)

          Java GC

          Java General

          NoSQL

          Tech General

          Tech Master

          最新隨筆

          搜索

          •  

          積分與排名

          • 積分 - 896808
          • 排名 - 42

          最新評論

          閱讀排行榜

          評論排行榜

          2.11 ClassFilemethod_infofield_info中同時存在的Attribute

          2.11.1     Synthetic Attribute

          Synthetic Attribute用于指示當(dāng)前類、接口、方法或字段由編譯器生成,而不在源代碼中存在(不包含類初始函數(shù)和實例初始函數(shù))。相同的功能還有一種方式就是在類、接口、方法或字段的訪問權(quán)限中設(shè)置ACC_SYNTHETIC標記。

           

          Synthetic AttributeJDK1.1中引入,以支持內(nèi)嵌類和接口(nested classes and interfaces)。但是以我現(xiàn)在所知,這些功能都是可以通過ACC_SYNTHETIC標記來表達的,為什么還需要存在Synthetic Attribute呢?在什么樣的情況下會生成Synthetic Attribute項呢?我還沒有找到,需要繼續(xù)研究。

          Synthetic Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內(nèi)容的字節(jié)長度(0)。

           

          2.11.2     Signature Attribute

          Signature Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內(nèi)容的字節(jié)長度(2)。

          u2

          signature_index

          constant_pool中的索引,CONSTANT_Utf8_info類型。記錄當(dāng)前類型的簽名(類簽名、字段簽名、方法簽名)。

          JVM規(guī)范中沒有指定什么情況下需要生成Signature Attribute。但是從Signature的目的是用于泛型類型,可以推測Signature Attribute存在于當(dāng)前Signature Attribute所在類型是泛型(泛型類、泛型方法、泛型字段)的時候。它和field_infomethod_infothis_class一起對應(yīng)于局部變量中的LocalVariableTable AttributeLocalVariableTypeTable Attribute,他們同時都有descriptor版本和signature版本。

           

          2.11.3     Deprecated Attribute

          Deprecated Attribute指示當(dāng)前類、方法、字段已經(jīng)過時了,一些工具,如編譯器可以根據(jù)該Attribute提示用戶他們使用的類、方法、字段已經(jīng)過時了,最好使用最新版本的類、方法、字段。

          Deprecated Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內(nèi)容的字節(jié)長度(0)。

           

          2.11.4     RuntimeVisibleAnnotations Attribute

          RuntimeVisibleAnnotations Attribute記錄了當(dāng)前類、方法、字段在源代碼中定義的、在運行時可見的AnnotationJava程序可以通過反射函數(shù)獲取這些Annotation。一個attributes集合中只能包含一項RuntimeVisibleAnnotations Attribute,記錄所有運行時可見的Annotation

          RuntimeVisibleAnnotations Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內(nèi)容的字節(jié)長度。

          u2

          num_annotations

          annotations集合長度。

          annotation

          annotations[num_annotations]

          記錄所有運行時可見的annotation的集合。annotation類型詳見附錄E

           

          2.11.5     RuntimeInvisibleParameterAnotations Attribute

          RuntimeInvisibleAnnotations Attribute記錄了當(dāng)前類、方法、字段在源代碼中定義的、在運行時不可見的Annotation。默認情況下,這些Annotation是不可被Java提供的反射函數(shù)獲取的,需要通過和實現(xiàn)相關(guān)的機制來獲取這些Annotation。一個attributes集合中只能包含一項RuntimeInvisibleAnnotations Attribute,記錄所有運行時不可見的Annotation

          RuntimeInvisibleAnnotations Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內(nèi)容的字節(jié)長度。

          u2

          num_annotations

          annotations集合長度。

          annotation

          annotations[num_annotations]

          記錄所有運行時不可見的annotation的集合。annotation類型詳見附錄E

           


           

          總體格式

          magic(0xCAFEBABE)

          version(major.minor)

          constant pool

          CONSTANT_Utf8_info(1)

          CONSTANT_Integer_info(3)

          CONSTANT_Float_info(4)

          CONSTANT_Long_info(5)

          CONSTANT_Double_info(6)

          CONSTANT_Class_info(7)

          CONSTANT_String_info(8)

          CONSTANT_Fieldref_info(9)

          CONSTANT_Methodref_info(10)

          CONSTANT_InterfaceMethodref_info(11)

          CONSTANT_NameAndType_info(12)

          access_flags

          this_class

          super_class

          interfaces

          fields

          access_flags

          name

          descriptor

          attributes

          ConstantValue Attribute

          Synthetic Attribute

          Signature Attribute

          Deprecated Attribute

          RuntimeVisibleAnnotations Attribute

          RuntimeInvisibleAnnotations Attribute

          methods

          access_flags

          name

          descriptor

          attributes

          Code Attribute

          StackMapTable Attribute

          LineNumberTable Attribute

          LocalVariableTable Attribute

          LocalVariableTypeTable Attribute

          Exceptions Attribute

          RuntimeVisibleParameterAnnotations Attribute

          RuntimeInvisibleParameterAnnotations Attribute

          AnnotationDefault Attribute

          Synthetic Attribute

          Signature Attribute

          Deprecated Attribute

          RuntimeVisibleAnnotations Attribute

          RuntimeInvisibleAnnotations Attribute

          attributes

          InnerClasses Attribute

          EnclosingMethod Attribute

          SourceFile Attribute

          SourceDebugExtension Attribute

          Synthetic Attribute

          Signature Attribute

          Deprecated Attribute

          RuntimeVisibleAnnotations Attribute

          RuntimeInvisibleAnnotations Attribute


           

          附件A Java字節(jié)碼中的類和接口名

           

          Java字節(jié)碼中類和接口名主要表現(xiàn)以下幾點:

          1.       類和接口名都是以全限定名的方式存放(包名加類或接口名)。

          2.       在源代碼中的點分隔符”.”在字節(jié)碼中以斜杠”/”代替。如:“java.lang.Object-> java/lang/Object

          3.       數(shù)組類型名做了特殊處理。如:“int[][]-> [[I”、“Thread[]->[Ljava/lang/Thread”。詳見附錄BJava字節(jié)碼中的數(shù)組類型名

           

           

          附件B Java字節(jié)碼中的數(shù)組類型名

           

          Java中,數(shù)組被認為是類,因而它也有對應(yīng)的類名表示,而Java字節(jié)碼為數(shù)組名指定了特定的格式:

          1. 所有數(shù)組名都以“[”開頭n維數(shù)組有n個“[”。

          2. 對引用類型的數(shù)組,在“[”后加“L后加引用類型的全限定名。

          3. 對基本類型,在“[”后加基本類型的對應(yīng)字符

          基本類型對應(yīng)字符表

          基本類型

          對應(yīng)字符

          byte

          B

          char

          C

          double

          D

          float

          F

          int

          I

          long

          J

          short

          S

          boolean

          Z

           

          附件C 描述符(Descriptor

           

          描述符(Descriptor)定義了字段或方法的類型(A descriptor is a string representing the type of a field or method.這段描述感覺不怎么精確)。它存放在constant pool中的CONSTANT_Utf8_info類型項中。

           

          1.       字段描述符(Field Descriptor

          字段描述符是定義了字段、局部變量、參數(shù)等類型的字符串。即附錄A中的類或接口名。

          語法定義:

          FieldDescrptor :

          FieldType

           

          BaseType BCDFIJSZ(參考附錄B中的基本類型對應(yīng)字符表)

          ObjectType LfullClassName;

          ArrayType [+BaseType | [+ObjectType

          FieldType BaseType | ObjectType | ArrayType

          如:[[D -> double[][][Ljava/lang/Thread; -> Thread[]I->intLjava/lang/Object; -> Object

           

          2.       方法描述符(Method Descriptor

          方法描述符是定義了方法參數(shù)、方法返回等信息的字符串。

          語法定義:

          MethodDescriptor:

                   ParameterDescriptor*ReturnDescriptor

           

          ParameterDescriptor FieldType

          ReturnDescriptor FieldType | VoidDescriptor

          VoidDescriptor V

          如:void methodint i, Object obj-> (ILjava/lang/Object;)V

          Object getValue()-> ( )Ljava/lang/Object;

          Object mymethod(int i, double d, Object o) -> (IDLjava/lang/Object;)Ljava/lang/Object;

           

          附件D 簽名(Signature

           

          簽名(Signature)定義了類、字段或方法的泛型類型信息(A signature is a string representing the generic type of a field or method, or generic type information for a class declaration. 這段描述感覺不怎么精確)。它也存放在constant pool中的CONSTANT_Utf8_info類型項中。

          它存在于Signature Attribute中,只有包含泛型的類、字段、方法才會產(chǎn)生Signature Attribute

           

          簽名信息并不是給JVM用的,而是用于編譯、調(diào)試、反射。

           

          1.       類簽名

          語法定義:

          ClassSignature:

          FormalTypeParametersopt SuperclassSignature SuperinterfaceSignature*

           

          FormalTypeParameters:

          <FormalTypeParameter+>

          FormalTypeParameter:

          Identifier ClassBound InterfaceBound*

          ClassBound:

          : FieldTypeSignatureopt

          InterfaceBound:

          : FieldTypeSignature

          SuperclassSignature:

          ClassTypeSignature

          SuperinterfaceSignature:

          ClassTypeSignature

          FieldTypeSignature:

          ClassTypeSignature

          ArrayTypeSignature

          TypeVariableSignature

          ClassTypeSignature:

          L PackageSpecifier* SimpleClassTypeSignature

          ClassTypeSignatureSuffix* ;

          PackageSpecifier:

          Identifier / PackageSpecifier*

          SimpleClassTypeSignature:

          Identifier TypeArgumentsopt

          ClassTypeSignatureSuffix:

          . SimpleClassTypeSignature

          TypeVariableSignature:

          T Identifier ;

          TypeArguments:

          <TypeArgument+>

          TypeArgument:

          WildcardIndicatoropt FieldTypeSignature

          *

          WildcardIndicator:

          +

          -

          ArrayTypeSignature:

          [TypeSignature

          TypeSignature:

          FieldTypeSignature

          BaseType

          以上定義沒有看懂??例子如:

          class MyClass<T> { } 定義的類,產(chǎn)生如下的簽名:

          <T:Ljava/lang/Object;>Ljava/lang/Object;

          而對以下類定義:

          class MyClass<T1, T2> extends ClassFileParser implements IndexParser {

          }

          則產(chǎn)生如下簽名:

          <T1:Ljava/lang/Object;T2:Ljava/lang/Object;>Lorg/levin/classfilereader/ClassFileParser;Lorg/levin/classfilereader/IndexParser;

           

          2.       字段簽名

          語法定義如上,沒能看懂。從Tomcat代碼中的Digester.class文件中可以解析得到如下的例子:

          Ljava/util/HashMap<Ljava/lang/String;Ljava/util/Stack<Ljava/lang/String;>;>;(對應(yīng)的descriptor:“Ljava/util/HashMap;”)

          Ljava/util/Stack<Ljava/lang/Object;>;(對應(yīng)的descriptor:“Ljava/util/Stack;”)

           

          3.       方法簽名

          語法定義:

          MethodTypeSignature:

          FormalTypeParametersopt (TypeSignature*) ReturnType

          ThrowsSignature*

          ReturnType:

          TypeSignature

          VoidDescriptor

          ThrowsSignature:

          ^ClassTypeSignature

          ^TypeVariableSignature

          也沒能看懂。同樣從Tomcat代碼中的Digester.class文件中可以解析得到如下例子:

          (Ljava/lang/String;Ljava/lang/Class<*>;Ljava/lang/String;)V(對應(yīng)descriptor:“(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;)V”)

          (Ljava/lang/String;Ljava/lang/Class<*>;Ljava/lang/String;Z)V(對應(yīng)descriptor:“(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Z)V”)

          ()Ljava/util/Map<Ljava/lang/String;Ljava/net/URL;>;(對應(yīng)descriptor:“()Ljava/util/Map;”)

           

          附錄Eannotation結(jié)構(gòu)和element_value結(jié)構(gòu)

           

          1.      annotation結(jié)構(gòu)

          每一項annotation結(jié)構(gòu)記錄一項用戶定義的annotation的值。如:

              @Test(id = 4, description = "description", useCase = @UseCase())

              @UseCase()

              void testExecute(int a) {

              }

          編譯器會為該方法生成兩項annotation。每項annotation指定了annotation的類型和鍵值對。

          annotation結(jié)構(gòu)

          type

          descriptor

          remark

          u2

          type_index

          constant_pool中的索引。CONSTANT_Utf8_info類型。以字段描述符(field descriptor)方式記錄當(dāng)前結(jié)構(gòu)表示的annotation類型。

          u2

          num_element_value_pairs

          記錄當(dāng)前annotation中的鍵值對數(shù)。

          element_value_pair

          記錄每項annotation中的鍵值對表。

          u2

          element_name_index

          constant_pool中的索引。CONSTANT_Utf8_info類型。記錄當(dāng)前annotation中當(dāng)前鍵值對的鍵名。如上例的“id”、“description”等。

          element_value

          value

          當(dāng)前annotation中當(dāng)前鍵值對的值。詳見element_value結(jié)構(gòu)一節(jié)。

          element_value_pairs[num_element_value_pairs]

           

           

          2.      element_value結(jié)構(gòu)

          element_value結(jié)構(gòu)記錄了所有annotation類型的鍵值對中的值。它是一個聯(lián)合類型,可以表示多種類型的值。

          element_value結(jié)構(gòu)

          type

          descriptor

          remark

          u1

          tag

          tag記錄了當(dāng)前annotation鍵值對中值的類型,’B’’C’’D’’F’’I’’J’’S’’Z’表示基本類型(見附錄B中的基本類型對應(yīng)表);其他的合法值有:

          ’s’ -> String

          ‘e’ -> enum constant

          ‘c’ -> class

          ‘@’ -> annotation type

          ‘[‘ -> array

          value 聯(lián)合體類型(union

          union類型,記錄當(dāng)前annotaion鍵值對中的值。

          u2

          constant_value_index

          constant_pool中的索引,索引項必須是常量類型。當(dāng)tag中的值為’B’ ‘C’ ‘D’ ‘F’ ‘I’ ‘J’ ‘S’ ‘Z’ ‘s’時該項有效。

          enum_const_value

          當(dāng)tag值為’e’時,該項有效。記錄枚舉類型值。

          u2

          type_name_index

          constant_pool中的索引,CONSTANT_Utf8_info類型。記錄當(dāng)前枚舉類型二進制名(binary name,好像就是類型名,以descriptor的形式表示)。

          u2

          const_name_index

          constant_pool中的索引,CONSTANT_Utf8_info類型。記錄當(dāng)前枚舉類型的值(枚舉類型內(nèi)部成員字符串)。

          enum_const_value

          u2

          class_info_index

          constant_pool中的索引,CONSTANT_Utf8_info類型。以descriptor記錄當(dāng)前值所表達的Class類型。當(dāng)tag值為’c’時,該項有效。

          annotation

          annotation_value

          當(dāng)tag值為’@’時,該項有效。記錄當(dāng)前annotation鍵值對中的值為內(nèi)嵌的annotation

          array_value

          當(dāng)tag值為’[‘時,該項有效。記錄當(dāng)前annotation鍵值對中的值為數(shù)組類型。

          u2

          num_values

          數(shù)組的長度。

          element_value

          values[num_values]

          每一項記錄數(shù)組中的值。

          array_value

          value

           

          注:從這個結(jié)構(gòu)中,我們也可以得出annotation中可以設(shè)置的值類型:

          1.       基本類型值(bytechardoublefloatintlongshortboolean

          2.       字符串(String

          3.       枚舉(enum

          4.       類實例(Class

          5.       嵌套注解類型(annotation

          6.       以上所有以上類型的一維數(shù)組。

                                                                                                      于2010-12-19日

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

          FeedBack:
          # re: Java字節(jié)碼(.class文件)格式詳解(三)
          2012-09-28 09:48 | tj
          很詳細, 多謝好文  回復(fù)  更多評論
            
          # re: Java字節(jié)碼(.class文件)格式詳解(三)
          2013-01-06 00:33 | Yeah
          多謝,多謝,學(xué)習(xí)中  回復(fù)  更多評論
            
          # re: Java字節(jié)碼(.class文件)格式詳解(三)
          2013-01-06 00:33 | Yeah
          學(xué)習(xí)中,多謝多謝  回復(fù)  更多評論
            
          主站蜘蛛池模板: 油尖旺区| 饶河县| 万源市| 同江市| 安义县| 福安市| 怀仁县| 洛浦县| 揭阳市| 安庆市| 广安市| 资阳市| 周至县| 徐州市| 河南省| 栾川县| 江都市| 淮滨县| 鹤庆县| 子长县| 芒康县| 察隅县| 武宁县| 安阳县| 含山县| 钦州市| 大连市| 波密县| 湄潭县| 三明市| 双城市| 青浦区| 洛川县| 酒泉市| 大渡口区| 多伦县| 樟树市| 宜章县| 建平县| 陆丰市| 高雄县|