上善若水
          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

          2.11 ClassFilemethod_infofield_info中同時存在的Attribute

          2.11.1     Synthetic Attribute

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

           

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

          Synthetic Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內容的字節長度(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內容的字節長度(2)。

          u2

          signature_index

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

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

           

          2.11.3     Deprecated Attribute

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

          Deprecated Attribute

          type

          descriptor

          remark

          u2

          attribute_name_index

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

          u4

          attribute_length

          Attribute內容的字節長度(0)。

           

          2.11.4     RuntimeVisibleAnnotations Attribute

          RuntimeVisibleAnnotations Attribute記錄了當前類、方法、字段在源代碼中定義的、在運行時可見的AnnotationJava程序可以通過反射函數獲取這些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內容的字節長度。

          u2

          num_annotations

          annotations集合長度。

          annotation

          annotations[num_annotations]

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

           

          2.11.5     RuntimeInvisibleParameterAnotations Attribute

          RuntimeInvisibleAnnotations Attribute記錄了當前類、方法、字段在源代碼中定義的、在運行時不可見的Annotation。默認情況下,這些Annotation是不可被Java提供的反射函數獲取的,需要通過和實現相關的機制來獲取這些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內容的字節長度。

          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字節碼中的類和接口名

           

          Java字節碼中類和接口名主要表現以下幾點:

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

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

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

           

           

          附件B Java字節碼中的數組類型名

           

          Java中,數組被認為是類,因而它也有對應的類名表示,而Java字節碼為數組名指定了特定的格式:

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

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

          3. 對基本類型,在“[”后加基本類型的對應字符

          基本類型對應字符表

          基本類型

          對應字符

          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

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

          語法定義:

          FieldDescrptor :

          FieldType

           

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

          ObjectType LfullClassName;

          ArrayType [+BaseType | [+ObjectType

          FieldType BaseType | ObjectType | ArrayType

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

           

          2.       方法描述符(Method Descriptor

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

          語法定義:

          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中,只有包含泛型的類、字段、方法才會產生Signature Attribute

           

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

           

          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> { } 定義的類,產生如下的簽名:

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

          而對以下類定義:

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

          }

          則產生如下簽名:

          <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;>;>;(對應的descriptor:“Ljava/util/HashMap;”)

          Ljava/util/Stack<Ljava/lang/Object;>;(對應的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(對應descriptor:“(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;)V”)

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

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

           

          附錄Eannotation結構和element_value結構

           

          1.      annotation結構

          每一項annotation結構記錄一項用戶定義的annotation的值。如:

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

              @UseCase()

              void testExecute(int a) {

              }

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

          annotation結構

          type

          descriptor

          remark

          u2

          type_index

          constant_pool中的索引。CONSTANT_Utf8_info類型。以字段描述符(field descriptor)方式記錄當前結構表示的annotation類型。

          u2

          num_element_value_pairs

          記錄當前annotation中的鍵值對數。

          element_value_pair

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

          u2

          element_name_index

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

          element_value

          value

          當前annotation中當前鍵值對的值。詳見element_value結構一節。

          element_value_pairs[num_element_value_pairs]

           

           

          2.      element_value結構

          element_value結構記錄了所有annotation類型的鍵值對中的值。它是一個聯合類型,可以表示多種類型的值。

          element_value結構

          type

          descriptor

          remark

          u1

          tag

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

          ’s’ -> String

          ‘e’ -> enum constant

          ‘c’ -> class

          ‘@’ -> annotation type

          ‘[‘ -> array

          value 聯合體類型(union

          union類型,記錄當前annotaion鍵值對中的值。

          u2

          constant_value_index

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

          enum_const_value

          tag值為’e’時,該項有效。記錄枚舉類型值。

          u2

          type_name_index

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

          u2

          const_name_index

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

          enum_const_value

          u2

          class_info_index

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

          annotation

          annotation_value

          tag值為’@’時,該項有效。記錄當前annotation鍵值對中的值為內嵌的annotation

          array_value

          tag值為’[‘時,該項有效。記錄當前annotation鍵值對中的值為數組類型。

          u2

          num_values

          數組的長度。

          element_value

          values[num_values]

          每一項記錄數組中的值。

          array_value

          value

           

          注:從這個結構中,我們也可以得出annotation中可以設置的值類型:

          1.       基本類型值(bytechardoublefloatintlongshortboolean

          2.       字符串(String

          3.       枚舉(enum

          4.       類實例(Class

          5.       嵌套注解類型(annotation

          6.       以上所有以上類型的一維數組。

                                                                                                      于2010-12-19日

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

          FeedBack:
          # re: Java字節碼(.class文件)格式詳解(三)
          2012-09-28 09:48 | tj
          很詳細, 多謝好文  回復  更多評論
            
          # re: Java字節碼(.class文件)格式詳解(三)
          2013-01-06 00:33 | Yeah
          多謝,多謝,學習中  回復  更多評論
            
          # re: Java字節碼(.class文件)格式詳解(三)
          2013-01-06 00:33 | Yeah
          學習中,多謝多謝  回復  更多評論
            
          主站蜘蛛池模板: 揭阳市| 清苑县| 汤原县| 丰都县| 迁西县| 堆龙德庆县| 武邑县| 许昌市| 沧州市| 沁源县| 阿勒泰市| 承德县| 汾西县| 始兴县| 儋州市| 德阳市| 诸城市| 嵊泗县| 沁阳市| 呼伦贝尔市| 廉江市| 鲁山县| 肇源县| 津南区| 中西区| 荥阳市| 临清市| 社会| 诸城市| 泽库县| 名山县| 苗栗市| 南靖县| 治多县| 千阳县| 河西区| 正镶白旗| 寿宁县| 铜鼓县| 凤冈县| 交城县|