Dalvik 可執行格式

本文檔描述了.dex檔案的佈局和內容,這些檔案用於保存一組類別定義及其關聯的附加資料。

類型指南

姓名描述
位元組8 位元有符號整數
優位元組8 位元無符號整數
短的16 位元有符號 int,小端字節序
超短16 位元無符號整數,小尾數
整數32 位元有符號 int、小端字節序
單位32 位元無符號整數,小尾數
長的64 位元有符號 int、小端字節序
烏龍64 位元無符號整數,小尾數
斯萊布128有符號 LEB128,可變長度(見下文)
烏萊布128無符號 LEB128,可變長度(見下文)
烏萊布128p1無符號 LEB128 加1 ,可變長度(見下文)

LEB128

LEB128(「 Little - Endian Base 128 」)是用於任意有符號或無符號整數量的可變長度編碼。此格式借用自DWARF3規範。在.dex檔案中,LEB128 僅用於編碼 32 位元數量。

每個 LEB128 編碼值由一到五個位元組組成,它們一起代表一個 32 位元值。每個位元組都設定了其最高有效位,序列中的最後一個位元組除外,該位元組的最高有效位已清除。每個位元組的其餘七位元是有效負載,數量的最低有效七位元在第一個位元組中,接下來的七位元在第二個位元組中,依此類推。對於帶有符號的 LEB128 ( sleb128 ),序列中最後一個位元組的最高有效負載位元將進行符號擴展以產生最終值。在無符號情況下 ( uleb128 ),任何未明確表示的位元都被解釋為0

兩位元組 LEB128 值的位​​元圖
第一個位元組第二個位元組
1位元6位元5位元4位元3位元2位元1位元0 0位元13位元12位元11位元10位元9位元8位元7

變體uleb128p1用來表示有符號值,其中表示的是編碼為uleb128的值加一。這使得-1 (或被認為是無符號值0xffffffff )的編碼 - 但沒有其他負數 - 成為一個字節,並且在所表示的數字必須為非負數或-1 (或0xffffffff ),並且不允許其他負值(或不太可能需要大的無符號值)。

以下是一些格式範例:

編碼序列作為sleb128作為uleb128作為uleb128p1
00 0 0 -1
01 1 1 0
7f -1 127 126
80 7f -128 16256 16255

文件佈局

姓名格式描述
標頭標題項標題
字串ID字串_id_項目[]字串標識符列表。這些是該檔案使用的所有字串的標識符,用於內部命名(例如類型描述符)或作為代碼引用的常數物件。此清單必須使用 UTF-16 代碼點值(不以區域設定敏感的方式)按字串內容排序,且不得包含任何重複的條目。
類型ID類型_id_項目[]類型標識符列表。這些是該文件引用的所有類型(類別、陣列或基本類型)的標識符,無論是否在文件中定義。此清單必須按string_id索引排序,且不得包含任何重複的條目。
原型ID原型_id_項目[]方法原型識別碼列表。這些是該文件引用的所有原型的識別碼。此清單必須按返回類型(按type_id索引)主順序排序,然後按參數列表(字典順序,各個參數按type_id索引排序)排序。該清單不得包含任何重複的條目。
欄位ID字段_id_項目[]字段標識符列表。這些是該文件引用的所有欄位的標識符,無論是否在文件中定義。此清單必須進行排序,其中定義類型(按type_id索引)是主要順序,欄位名稱(按string_id索引)是中間順序,類型(按type_id索引)是次要順序。該清單不得包含任何重複的條目。
方法ID方法_id_項目[]方法標識符列表。這些是該文件引用的所有方法的標識符,無論是否在文件中定義。此列表必須進行排序,其中定義類型(按type_id索引)是主要順序,方法名稱(按string_id索引)是中間順序,方法原型(按proto_id索引)是次要順序。該清單不得包含任何重複的條目。
類別定義類別定義項[]類別定義列表。必須對類別進行排序,以便給定類別的超類別和實作的介面早於引用類別出現在清單中。此外,同名類別的定義在清單中多次出現也是無效的。
呼叫站台 ID呼叫站點 ID 項目[]呼叫站點標識符列表。這些是該文件引用的所有呼叫網站的標識符,無論是否在文件中定義。該列表必須按call_site_off的升序排序。
方法句柄方法句柄項目[]方法處理列表。該文件引用的所有方法句柄的列表,無論是否在文件中定義。此清單未排序,並且可能包含邏輯上對應於不同方法句柄實例的重複項。
數據優字節[]資料區域,包含上面列出的表格的所有支援資料。不同的項目有不同的對齊要求,如果需要的話,會在每個項目之前插入填充位元組以實現正確的對齊。
連結數據優字節[]靜態連結檔案中使用的資料。本文檔未指定本節中資料的格式。此部分在未連結的檔案中為空,運行時實作可以根據需要使用它。

位元域、字串和常數定義

DEX_FILE_MAGIC

嵌入 header_item 中

常數數組/字串DEX_FILE_MAGIC是必須出現在.dex檔案開頭才能被辨識的位元組清單。該值有意包含換行符( "\n"0x0a )和空位元組( "\0"0x00 ),以協助偵測某些形式的損壞。該值還將格式版本號編碼為三位十進制數字,預計隨著格式的發展,該版本號會隨著時間的推移而單調增加。

ubyte[8] DEX_FILE_MAGIC = { 0x64 0x65 0x78 0x0a 0x30 0x33 0x39 0x00 }
                        = "dex\n039\0"

注意: Android 9.0 版本中新增了對該格式039版本的支持,其中引入了兩個新的字節碼const-method-handleconst-method-type 。 (這些內容均在字節碼集表摘要中進行了描述。)在 Android 10 中,版本039擴展了 DEX 檔案格式,以包含僅適用於引導類別路徑上的 DEX 檔案的隱藏 API 資訊。

注意: Android 8.0 版本中新增了對該格式038版本的支援。版本038新增了新的字節碼( invoke-polymorphicinvoke-custom )和方法句柄的資料。

注意: Android 7.0 版本中新增了對該格式037版本的支援。在版本037之前,大多數 Android 版本都使用版本035的格式。 035037版本唯一的差異是預設方法的增加和invoke的調整。

注意:該格式的至少幾個早期版本已在廣泛使用的公共軟體版本中使用。例如,版本009用於Android平台的M3版本(2007年11月至12月),版本013用於Android平台的M5版本(2008年2月至3月)。在多個方面,這些早期版本的格式與本文檔中所述的版本有很大不同。

ENDIAN_CONSTANT 和 REVERSE_ENDIAN_CONSTANT

嵌入 header_item 中

常數ENDIAN_CONSTANT用於指示在其中找到它的檔案的位元組順序。儘管標準.dex格式是小尾數,但實作可以選擇執行位元組交換。如果實作遇到endian_tagREVERSE_ENDIAN_CONSTANT而不是ENDIAN_CONSTANT標頭,它將知道該檔案已從預期形式進行了位元組交換。

uint ENDIAN_CONSTANT = 0x12345678;
uint REVERSE_ENDIAN_CONSTANT = 0x78563412;

沒有索引

嵌入在class_def_item和debug_info_item中

常數NO_INDEX用於指示索引值不存在。

注意:該值未定義為0 ,因為這實際上通常是一個有效的索引。

NO_INDEX的所選值可表示為uleb128p1編碼中的單一位元組。

uint NO_INDEX = 0xffffffff;    // == -1 if treated as a signed int

access_flags 定義

嵌入在 class_def_item、encoded_field、encoded_method 和 InnerClass 中

這些標誌的位元欄位用於指示類別和類別成員的可存取性和整體屬性。

姓名價值對於類別(和InnerClass註解)對於領域對於方法
ACC_PUBLIC 0x1 public :隨處可見public :隨處可見public :隨處可見
ACC_私人0x2 * private :僅對定義類別可見private :僅對定義類別可見private :僅對定義類別可見
ACC_PROTECTED 0x4 * protected :對包和子類別可見protected :對包和子類別可見protected :對包和子類別可見
ACC_靜態0x8 * static :不是用外部this引用建構的static :定義類別的全域static :不接受this參數
ACC_FINAL 0x10 final :不可子類化final :構造後不可變final :不可覆蓋
ACC_SYNCHRONIZED 0x20 synchronized :在呼叫此方法時自動取得關聯鎖。

注意:只有當ACC_NATIVE也被設定時,該設定才有效。

ACC_VOLATILE 0x40 volatile :特殊的存取規則有助於執行緒安全
ACC_BRIDGE 0x40橋接方法,由編譯器自動新增為類型安全橋接
ACC_TRANSIENT 0x80 transient :預設不儲存序列化
ACC_VARARGS 0x80最後一個參數應被編譯器視為「其餘」參數
ACC_NATIVE 0x100 native :以本機程式碼實現
ACC_介面0x200 interface :可多重實現的抽象類
ACC_摘要0x400 abstract :不能直接實例化abstract :此類未實現
ACC_STRICT 0x800 strictfp :浮點運算的嚴格規則
ACC_SYNTHETIC 0x1000原始碼中沒有直接定義原始碼中沒有直接定義原始碼中沒有直接定義
ACC_註釋0x2000聲明為註解類
ACC_ENUM 0x4000聲明為枚舉類型聲明為枚舉值
(沒用過) 0x8000
ACC_CONSTRUCTOR 0x10000建構函數方法(類別或實例初始值設定項)
ACC_DECLARED_
同步
0x20000聲明synchronized

注意:這對執行沒有影響(除了反映此標誌本身)。

*僅允許在InnerClass註解中啟用,並且不得在class_def_item中啟用。

修改後的UTF-8編碼

作為對更簡單的舊版支援的讓步, .dex格式將其字串資料編碼為事實上的標準修改版 UTF-8 形式(以下稱為 MUTF-8)。此形式與標準 UTF-8 相同,除了:

  • 僅使用一位元組、二位元組和三位元組編碼。
  • U+10000U+10ffff範圍內的代碼點被編碼為代理對,每個代理對錶示為一個三位元組編碼值。
  • 代碼點U+0000以兩位元組形式編碼。
  • 純空位元組(值0 )表示字串的結尾,這是標準 C 語言解釋。

上面的前兩條可以概括為:MUTF-8是UTF-16的一種編碼格式,而不是Unicode字元的更直接的編碼格式。

上面的最後兩個項目使得可以同時將代碼點U+0000包含在字串中,並且仍然將其作為 C 風格的空終止字串進行操作。

然而, U+0000的特殊編碼意味著,與普通 UTF-8 不同,在一對 MUTF-8 字串上呼叫標準 C 函數strcmp()的結果並不總是表示不相等字串比較的正確簽章結果。當考慮排序(不僅僅是相等)時,比較 MUTF-8 字串的最直接方法是逐個字元解碼它們,並比較解碼後的值。 (但是,更聰明的實現也是可能的。)

有關字元編碼的更多信息,請參閱Unicode 標準。 MUTF-8 實際上更接近(相對不太知名的)編碼CESU-8 ,而不是 UTF-8 本身。

編碼值編碼

嵌入到annotation_element和encoded_array_item中

encoded_value是(幾乎)任意分層結構資料的編碼片段。編碼既緊湊又易於解析。

姓名格式描述
(值參數 << 5) |值類型優位元組指示緊接其後的value的類型的位元組以及高位元三位中的可選澄清參數。請參閱下面的各種value定義。大多數情況下, value_arg編碼緊接在後的value的長度(以位元組為單位),如(size - 1) ,例如0表示該值需要 1 個位元組, 7表示該值需要8 個位元組;然而,也存在如下所述的例外情況。
價值優字節[]表示值的字節,長度可變,並且對於不同的value_type字節有不同的解釋,但始終是小端字節序。有關詳細信息,請參閱下面的各種值定義。

值格式

類型名稱value_type value_arg格式value格式描述
VALUE_BYTE 0x00 (無;必須為0超字節[1]有符號的一位元組整數值
VALUE_SHORT 0x02大小 - 1 (0…1)位元組[大小]有符號兩位元組整數值,符號擴展
VALUE_CHAR 0x03大小 - 1 (0…1)位元組[大小]無符號兩位元組整數值,零擴展
VALUE_INT 0x04尺寸 - 1 (0…3)位元組[大小]有符號四位元組整數值,符號擴展
VALUE_LONG 0x06尺寸 - 1 (0…7)位元組[大小]有符號八位元組整數值,符號擴展
VALUE_FLOAT 0x10尺寸 - 1 (0…3)位元組[大小]四位元組位模式,向右零擴展,並解釋為 IEEE754 32 位元浮點數值
VALUE_DOUBLE 0x11尺寸 - 1 (0…7)位元組[大小]八位元組位模式,向右零擴展,並解釋為 IEEE754 64 位元浮點值
VALUE_METHOD_TYPE 0x15尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為proto_ids部分的索引並表示方法類型值
VALUE_METHOD_HANDLE 0x16尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為method_handles部分的索引並表示方法句柄值
VALUE_STRING 0x17尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為string_ids部分的索引並表示字串值
值類型0x18尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為type_ids部分的索引並表示反射類型/類別值
VALUE_FIELD 0x19尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為field_ids部分的索引並表示反射字段值
VALUE_METHOD 0x1a尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為method_ids部分的索引並表示反射方法值
VALUE_ENUM 0x1b尺寸 - 1 (0…3)位元組[大小]無符號(零擴展)四位元組整數值,解釋為field_ids部分的索引並表示枚舉型別常數的值
VALUE_ARRAY 0x1c (無;必須為0編碼數組值的數組,採用下面的「 encoded_array format」指定的格式。 value的大小隱含在編碼中。
VALUE_ANNOTATION 0x1d (無;必須為0編碼註釋子註釋,採用下面「 encoded_annotation format」指定的格式。 value的大小隱含在編碼中。
VALUE_NULL 0x1e (無;必須為0 (沒有任何) null參考值
VALUE_BOOLEAN 0x1f布林值(0…1) (沒有任何)一位值; 0表示false1表示true 。該位在value_arg中表示。

編碼數組格式

姓名格式描述
尺寸烏萊布128數組中的元素數量
價值觀編碼值[大小]一系列按本節指定的格式按順序連接的size encoded_value位元組序列。

編碼註釋格式

姓名格式描述
類型idx烏萊布128註釋的類型。這必須是類別(不是數組或基元)類型。
尺寸烏萊布128此註解中名稱-值映射的數量
元素註釋元素[大小]註釋的元素,直接內聯表示(不是偏移量)。元素必須依string_id索引升序排序。

註釋元素格式

姓名格式描述
名稱_idx烏萊布128元素名稱,表示為string_ids部分的索引。該字串必須符合上面定義的MemberName的語法。
價值編碼值元素值

字串語法

.dex檔案中有多種最終引用字串的項目。以下 BNF 樣式定義指示這些字串可接受的語法。

簡單名稱

SimpleName是其他事物名稱語法的基礎。 .dex格式在這裡允許相當大的自由度(比大多數常見的源語言多得多)。簡而言之,簡單名稱由任何低位 ASCII 字母字元或數字、一些特定的低位 ASCII 符號以及大多數非控製字元、空格或特殊字元的非 ASCII 代碼點組成。從版本040開始,該格式還允許空格字元(Unicode Zs類別)。請注意,代理代碼點(在U+d800U+dfff範圍內)本身不被視為有效的名稱字符,但 Unicode 補充字符有效的(由SimpleNameChar規則的最終替代字符表示),並且它們應該在文件中表示為MUTF-8 編碼中的代理代碼點對。

簡單名稱
SimpleNameChar ( SimpleNameChar )*
簡單名稱字元
'A''Z'
| 'a' ... 'z'
| '0''9'
| ' '自 DEX 版本 040 起
| '$'
| '-'
| '_'
| U+00a0自 DEX 版本 040 起
| U+00a1U+1fff
| U+2000U+200a自 DEX 版本 040 起
| U+2010U+2027
| U+202f自 DEX 版本 040 起
| U+2030U+d7ff
| U+e000U+ffef
| U+10000U+10ffff

成員名字

由 field_id_item 和 method_id_item 使用

MemberName是類別成員的名稱,成員是欄位、方法和內部類別。

會員姓名
簡單名稱
| '<'簡單名稱'>'

全類名

FullClassName是完全限定的類別名,包含可選的套件說明符,後面接著必需的名稱。

完整類別名稱
可選包前綴SimpleName
可選包前綴
(簡單名稱'/' )*

類型描述符

由 type_id_item 使用

TypeDescriptor是任何類型的表示,包括基元、類別、陣列和void 。各個版本的涵義見下文。

類型描述符
'V'
|欄位類型描述符
字段類型描述符
非數組欄位類型描述符
| ( '[' * 1…255) NonArrayFieldTypeDescriptor
非陣列欄位類型描述符
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'全類別名稱';'

短描述符

由 proto_id_item 使用

ShortyDescriptor是方法原型的簡短形式表示,包括傳回類型和參數類型,但各種引用(類別或陣列)類型之間沒有區別。相反,所有引用類型都由單一'L'字元表示。

短描述符
ShortyReturnType ( ShortyFieldType )*
ShortyReturnType
'V'
|短字段類型
ShortyFieldType
'Z'
| 'B'
| 'S'
| 'C'
| 'I'
| 'J'
| 'F'
| 'D'
| 'L'

類型描述符語義

這就是TypeDescriptor的每個變體的含義。

句法意義
V void ;僅對返回類型有效
Z boolean
byte
S short
C char
int
J long
F float
D double
L完全/合格/姓名類別的fully.qualified.Name
[描述符descriptor符數組,可遞歸地用於數組數組,但超過 255 個維度是無效的。

項目和相關結構

本節包括.dex檔案中可能出現的每個頂級項目的定義。

標題項

出現在標題部分

對齊方式:4位元組

姓名格式描述
魔法ubyte[8] = DEX_FILE_MAGIC魔法值。有關更多詳細信息,請參閱上面“ DEX_FILE_MAGIC ”下的討論。
校驗和單位文件其餘部分的 adler32 校驗和(除了magic和此欄位之外的所有內容);用於檢測文件損壞
簽名超字節[20]文件其餘部分的 SHA-1 簽章(雜湊)(除了magicchecksum和此欄位之外的所有內容);用於唯一識別文件
文件大小單位整個檔案的大小(包括檔案頭),以位元組為單位
標頭大小單位 = 0x70標頭(整個部分)的大小,以位元組為單位。這允許至少有限數量的向後/向前相容性而不會使格式無效。
位元組序標籤uint = ENDIAN_CONSTANT位元組序標記。有關更多詳細信息,請參閱上面“ ENDIAN_CONSTANTREVERSE_ENDIAN_CONSTANT ”下的討論。
連結大小單位連結部分的大小,如果該檔案不是靜態連結的,則為0
連結關閉單位從檔案開頭到連結部分的偏移量,如果link_size == 0則為0 。偏移量(如果非零)應該是link_data部分的偏移量。本文檔未指定所指向資料的格式;此標頭欄位(以及前一個)保留為鉤子以供運行時實現使用。
地圖關閉單位從檔案開頭到映射項的偏移量。偏移量必須非零,應該是data部分的偏移量,資料應該採用下面「 map_list 」指定的格式。
字串 ID 大小單位字串標識符列表中的字串計數
字串_ids_關閉單位從檔案開頭到字串識別碼清單的偏移量,如果string_ids_size == 0 ,則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於string_ids部分的開頭。
類型 ID 大小單位類型識別符清單中的元素計數,最多 65535
類型_ids_關閉單位從檔案開頭到類型標識符清單的偏移量,如果type_ids_size == 0則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於type_ids部分的開頭。
原型 ID 大小單位原型識別碼清單中的元素數量,最多 65535
proto_ids_off單位從檔案開頭到原型識別符清單的偏移量,如果proto_ids_size == 0則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於proto_ids部分的開頭。
欄位 ID 大小單位字段標識符列表中的元素計數
字段 ID 關閉單位從檔案開頭到欄位識別碼清單的偏移量,如果field_ids_size == 0 0 則為0 。偏移量(如果非零)應位於field_ids部分的開頭。
方法ID大小單位方法標識符列表中的元素計數
方法_ids_關閉單位從檔案開頭到方法標識符清單的偏移量,如果method_ids_size == 0則為0 。偏移量(如果非零)應位於method_ids部分的開頭。
類別定義大小單位類別定義清單中的元素計數
類別定義關閉單位從檔案開頭到類別定義清單的偏移量,如果class_defs_size == 0則為0 (誠然,這是一個奇怪的邊緣情況)。偏移量(如果非零)應位於class_defs部分的開頭。
數據大小單位data部分的大小(以位元組為單位)。必須是 sizeof(uint) 的偶數倍。
數據關閉單位從檔案開頭到data部分開頭的偏移量。

地圖列表

出現在資料部分

引自 header_item

對齊方式:4位元組

這是文件全部內容的清單(依序)。它包含一些關於header_item的冗餘,但旨在成為用於迭代整個文件的簡單形式。給定類型在映射中最多只能出現一次,但除了格式其餘部分隱含的限制之外,類型的出現順序沒有任何限制(例如, header部分必須先出現,後跟string_ids部分等)。此外,映射條目必須按初始偏移量排序,且不得重疊。

姓名格式描述
尺寸單位清單的大小(以條目為單位)
清單地圖項目[大小]列表的元素

地圖項目格式

姓名格式描述
類型超短物品類型;請參閱下表
沒用過超短(沒用過)
尺寸單位在指定偏移處找到的項目數的計數
抵銷單位從檔案開頭到相關項目的偏移量

類型代碼

物品種類持續的價值項目大小(以位元組為單位)
標題項TYPE_HEADER_ITEM 0x0000 0x70
字串_id_項目TYPE_STRING_ID_ITEM 0x0001 0x04
類型_id_項目TYPE_TYPE_ID_ITEM 0x0002 0x04
原型 ID 項目TYPE_PROTO_ID_ITEM 0x0003 0x0c
欄位 ID 項TYPE_FIELD_ID_ITEM 0x0004 0x08
方法_id_項目TYPE_METHOD_ID_ITEM 0x0005 0x08
類別定義項TYPE_CLASS_DEF_ITEM 0x0006 0x20
呼叫站點 ID 項目TYPE_CALL_SITE_ID_ITEM 0x0007 0x04
方法句柄項TYPE_METHOD_HANDLE_ITEM 0x0008 0x08
地圖列表類型地圖列表0x1000 4 + (商品尺寸 * 12)
類型清單類型_類型_列表0x1001 4 + (商品尺寸 * 2)
註釋集引用列表TYPE_ANNOTATION_SET_REF_LIST 0x1002 4 + (商品尺寸 * 4)
註釋設定項TYPE_ANNOTATION_SET_ITEM 0x1003 4 + (商品尺寸 * 4)
類別資料項TYPE_CLASS_DATA_ITEM 0x2000隱含的;必須解析
代碼項類型代碼項目0x2001隱含的;必須解析
字串資料項TYPE_STRING_DATA_ITEM 0x2002隱含的;必須解析
偵錯資訊項TYPE_DEBUG_INFO_ITEM 0x2003隱含的;必須解析
註釋項TYPE_ANNOTATION_ITEM 0x2004隱含的;必須解析
編碼數組項TYPE_ENCODED_ARRAY_ITEM 0x2005隱含的;必須解析
註釋目錄項TYPE_ANNOTATIONS_DIRECTORY_ITEM 0x2006隱含的;必須解析
隱藏的api_class_data_item TYPE_HIDDENAPI_CLASS_DATA_ITEM 0xF000隱含的;必須解析

字串_id_項目

出現在 string_ids 部分

對齊方式:4位元組

姓名格式描述
字串資料關閉單位從檔案開頭到此項目的字串資料的偏移量。偏移量應該是data部分中的某個位置,並且資料應該採用下面“ string_data_item ”指定的格式。偏移量沒有對齊要求。

字串資料項

出現在資料部分

對齊方式:無(位元組對齊)

姓名格式描述
utf16_大小烏萊布128該字串的大小,以 UTF-16 代碼單元表示(在許多系統中是「字串長度」)。也就是說,這是字串的解碼長度。 (編碼長度由0位元組的位置暗示。)
數據優字節[]一系列 MUTF-8 代碼單元(也稱為八位元組、位元組),後面跟著一個值為0的位元組。有關資料格式的詳細資訊和討論,請參閱上面的「MUTF-8(修改的 UTF-8)編碼」。

注意:包含 UTF-16 代理代碼單元(即U+d800U+dfff )(的編碼形式)的字串是可以接受的,無論是獨立的還是相對於通常的編碼而言無序的將Unicode 轉換為UTF-16。如果合適的話,由字串的更高級別的使用來拒絕此類無效編碼。

類型_id_項目

出現在 type_ids 部分

對齊方式:4位元組

姓名格式描述
描述符_idx單位此類型的描述符字串的string_ids清單中的索引。該字串必須符合上面定義的TypeDescriptor語法。

原型 ID 項目

出現在proto_ids部分

對齊方式:4位元組

姓名格式描述
短IDX單位該原型的短格式描述符字串的string_ids列表中的索引。字串必須符合上面定義的ShortyDescriptor語法,並且必須對應於此項目的傳回類型和參數。
返回類型idx單位type_ids清單中該原型傳回類型的索引
參數_關閉單位從檔案開頭到此原型的參數類型清單的偏移量,如果此原型沒有參數,則為0 。該偏移量如果非零,則應位於data部分,並且其中的資料應採用下面"type_list"指定的格式。此外,清單中不應引用void類型。

欄位 ID 項

出現在 field_ids 部分

對齊方式:4位元組

姓名格式描述
類別idx超短此欄位定義者的type_ids清單的索引。這必須是類別類型,而不是陣列或基本類型。
類型idx超短此欄位類型的type_ids清單的索引
名稱_idx單位string_ids清單中的索引以取得該欄位的名稱。該字串必須符合上面定義的MemberName的語法。

方法_id_項目

出現在method_ids部分

對齊方式:4位元組

姓名格式描述
類別idx超短此方法的定義者的type_ids清單的索引。這必須是類別或陣列類型,而不是原始類型。
原型idx超短此方法原型的proto_ids列表的索引
名稱_idx單位string_ids清單中的索引以取得此方法的名稱。該字串必須符合上面定義的MemberName的語法。

類別定義項

出現在class_defs部分

對齊方式:4位元組

姓名格式描述
類別idx單位此類別的type_ids列表的索引。這必須是類別類型,而不是陣列或基本類型。
訪問標誌單位類別的訪問標誌( publicfinal等)。有關詳細信息,請參閱“ access_flags定義”。
超類_idx單位超類別的type_ids列表的索引,或者如果此類沒有超類別(即,它是根類,如Object ),則為常數值NO_INDEX 。如果存在,則它必須是類別類型,而不是陣列或基本類型。
介面關閉單位從檔案開頭到介面清單的偏移量,如果沒有則為0 。這個偏移量應該在data部分,並且那裡的資料應該採用下面“ type_list ”指定的格式。清單中的每個元素都必須是類別類型(不是陣列或基本類型),並且不能有任何重複項。
來源檔案idx單位string_ids清單中包含此類(至少是大部分)原始來源的檔案名稱的索引,或特殊值NO_INDEX來表示缺少此資訊。任何給定方法的debug_info_item都可能會覆寫該來源文件,但預期大多數類別僅來自一個來源文件。
註釋_關閉單位從文件開頭到此類的註釋結構的偏移量,如果此類上沒有註釋,則為0 。如果該偏移量非零,則應位於data部分,並且其中的資料應採用下面「 annotations_directory_item 」指定的格式,所有項目都引用此類作為定義者。
類別資料關閉單位從檔案開頭到此項的關聯類別資料的偏移量,如果該類別沒有類別數據,則為0 。 (例如,如果此類是標記接口,則可能是這種情況。)偏移量如果非零,則應位於data部分,並且那裡的資料應採用下面“ class_data_item ”指定的格式,所有項目都引用此類別作為定義者。
靜態值關閉單位從檔案開頭到static欄位初始值清單的偏移量,如果沒有則為0 (且所有static欄位都會使用0null進行初始化)。這個偏移量應該在data部分,並且那裡的資料應該採用下面「 encoded_array_item 」指定的格式。陣列的大小必須不大於該類別聲明的static欄位的數量,且元素與static欄位的對應順序與對應的field_list中宣告的順序相同。每個數組元素的類型必須與其對應欄位的聲明類型相符。如果數組中的元素少於static字段,則剩餘字段將使用適合類型的0null進行初始化。

呼叫站點 ID 項目

出現在 call_site_ids 部分

對齊方式:4位元組

姓名格式描述
呼叫站點關閉單位從檔案開頭到呼叫站點定義的偏移量。偏移量應該在資料部分,並且那裡的資料應該採用下面“call_site_item”指定的格式。

呼叫站點項目

出現在資料部分

對齊方式:無(位元組對齊)

call_site_item 是一個encoded_array_item,其元素對應到提供給引導連結器方法的參數。前三個參數是:

  1. 表示引導連結器方法的方法句柄 (VALUE_METHOD_HANDLE)。
  2. 引導連結器應解析的方法名稱 (VALUE_STRING)。
  3. 與要解析的方法名稱的型別相對應的方法型別 (VALUE_METHOD_TYPE)。

任何附加參數都是傳遞給引導連結器方法的常數值。這些參數按順序傳遞,沒有任何類型轉換。

表示引導連結器方法的方法句柄必須具有傳回類型java.lang.invoke.CallSite 。前三個參數類型是:

  1. java.lang.invoke.Lookup
  2. java.lang.String
  3. java.lang.invoke.MethodType

任何附加參數的參數類型由它們的常數值決定。

方法句柄項

出現在method_handles部分

對齊方式:4位元組

姓名格式描述
方法句柄類型超短方法句柄的類型;請參閱下表
沒用過超短(沒用過)
欄位或方法 ID超短欄位或方法ID取決於方法手把類型是訪客還是方法呼叫者
沒用過ushort (沒用過)

方法處理類型程式碼

持續的價值描述
method_handle_type_static_put 0x00方法句柄是靜態場設定器(訪客)
method_handle_type_static_get 0x01方法句柄是靜態欄位getter(訪客)
method_handle_type_instance_put 0x02方法句柄是一個實例字段設定器(訪問者)
method_handle_type_instance_get 0x03方法句柄是一個實例字段getter(訪問者)
method_handle_type_invoke_static 0x04方法句柄是靜態方法呼叫器
method_handle_type_invoke_instance 0x05方法句柄是實例方法呼叫器
method_handle_type_invoke_constructor 0x06方法句柄是建構函式方法呼叫器
method_handle_type_invoke_direct 0x07方法句柄是直接方法呼叫者
method_handle_type_invoke_interface 0x08方法句柄是介面方法呼叫器

class_data_item

從class_def_item引用

出現在資料部分

對齊:無(位元組對準)

姓名格式描述
static_fields_size Uleb128此項目中定義的靜態欄位數量
instance_fields_size Uleb128本項目中定義的實例字段數
direct_methods_size Uleb128此項目中定義的直接方法數量
virtual_methods_size Uleb128本項目中定義的虛擬方法數量
static_fields encoded_field [static_fields_size]定義的靜態字段,表示為一系列編碼元素。欄位必須按field_idx按越來越多的順序排序。
instance_fields encoded_field [instance_fields_size]定義的實例欄位表示為一系列編碼元素。欄位必須按field_idx按越來越多的順序排序。
Direct_Methods encoded_method [direct_methods_size]定義的直接( staticprivate或建構函數)方法表示為一系列編碼元素。該方法必須按method_idx按越來越多的順序排序。
virtual_methods encoded_method [virtual_methods_size]定義的虛擬(無staticprivate或建構函數)表示為一系列編碼元素。除非該項目代表的類別覆蓋,否則此列表不應包括繼承的方法。該方法必須按method_idx按越來越多的順序排序。虛擬方法的method_idx必須與任何直接方法都不相同。

注意:所有元素的field_idmethod_id實例必須參考相同的定義類別。

ENCODED_FIELD格式

姓名格式描述
field_idx_diff Uleb128索引此欄位的身份(包括名稱和描述符)中的field_ids列表,與列表中上一個元素的索引表示為差異。列表中第一個元素的索引直接表示。
access_flags Uleb128該欄位的存取標誌( publicfinal等)。有關詳細信息,請參見“ access_flags定義”。

ENCODED_METHOD格式

姓名格式描述
method_idx_diff Uleb128索引此方法的身份(包括名稱和描述符)的method_ids列表,與列表中上一個元素的索引表示為差異。列表中第一個元素的索引直接表示。
access_flags Uleb128該方法的訪問標誌( publicfinal等)。有關詳細信息,請參見“ access_flags定義”。
Code_off Uleb128從檔案的開頭偏移到此方法的程式碼結構,或者如果此方法是abstractnative 0 。偏移應為data部分中的位置。資料的格式由下面的「 code_item 」指定。

type_list

從class_def_item和proto_id_item引用

出現在資料部分

對齊:4個位元組

姓名格式描述
尺寸單位清單的大小,條目
清單type_item [size]列表的元素

type_item格式

姓名格式描述
type_idx ushort索引到type_ids列表

code_item

從encoded_method引用

出現在資料部分

對齊:4個位元組

姓名格式描述
registers_size ushort此程式碼使用的暫存器數量
ins_size ushort傳入的論點的單字數量與該代碼適用的方法
outs_size ushort該程式碼需要用於方法呼叫所需的傳出參數空間的單字數量
tries_size ushort此實例的try_item s數。如果非零,則在此實例之後的insns之後,它們顯示為tries數組。
debug_info_off單位從檔案的開頭偏移到此程式碼的偵錯資訊(行號 +本機變數資訊)序列,或如果沒有訊息,則為0 。偏移量(如果非零)應為data部分中的位置。資料的格式由下面的「 debug_info_item 」指定。
insns_size單位指令列表的尺寸,以16位元代碼單元為單位
insns ushort [insns_size]字節碼的實際數組。 insns數組中的程式碼格式由配套文件Dalvik字節碼指定。請注意,儘管這被定義為ushort的數組,但有些內部結構更喜歡四位元組對齊。同樣,如果恰好在一個匯總的文件中,則在單一ushort實例上而不是在較大的內部結構上進行交換。
填充ushort (可選) = 0兩個位元組的填充物使tries四位元組對齊。僅當tries_size是非零,而insns_size奇怪的情況下,此元素才存在。
嘗試try_item [tries_size] (可選)數組指示在程式碼異常中捕獲的位置以及如何處理它們。數組的元素必須在範圍內不重疊,從低位址到高位址。僅當tries_size不為零時,此元素才存在。
處理者encoded_catch_handler_list (可選)位元組代表捕獲類型和相關處理程序位址清單的清單。每個try_item都有一個位元組偏移到此結構中。僅當tries_size不為零時,此元素才存在。

try_item格式

姓名格式描述
start_addr單位啟動該條目涵蓋的程式碼區塊的位址。該位址是第一個涵蓋說明開始時的16位元代碼單元的計數。
insn_count ushort此條目涵蓋的16位元代碼單元的數量。涵蓋的最後一個程式碼單元(包含)是start_addr + insn_count - 1
handler_off ushort從關聯的encoded_catch_hander_listencoded_catch_handler位元組中,以將位元組偏移。這必須是對encoded_catch_handler的開始的偏移。

encoded_catch_handler_list格式

姓名格式描述
尺寸Uleb128此清單的大小,條目
清單encoded_catch_handler [handlers_size]直接表示的處理程​​序清單的實際清單(不是偏移),然後串聯

ENCODED_CATCH_HANDLER格式

姓名格式描述
尺寸SLEB128此清單中的捕獲類型數量。如果是非陽性的,則是捕獲類型數量的負數,捕獲器之後是捕獲的所有處理程序。例如: 0size意味著有一個捕獲的東西,但沒有明確的鍵入。 size2意味著有兩個明確輸入的捕獲量,沒有捕獲量。 -1size意味著有一個鍵入的捕獲量和全部捕獲。
處理者encoded_type_addr_pair [abs(size)] abs(size)編碼項目的流,每個捕獲的類型,都應按照測試類型進行測試。
catch_all_addr ULEB128 (可選)封閉式處理程序的字節碼位址。僅當size是非陽性時,此元素才存在。

ENCODED_TYPE_ADDR_PAIR格式

姓名格式描述
type_idx Uleb128索引到type_ids清單的擷取類型的類型
地址Uleb128相關異常處理程序的字節碼位址

debug_info_item

從code_item引用

出現在資料部分

對齊:無(位元組對準)

每個debug_info_item定義了一個矮人啟發的字節編碼狀態計算機,該機器在解釋時會發出位置表,並(可能)(可能) code_item的局部變數資訊。序列從變數長度的標頭開始(其長度取決於方法參數的數量),後面是狀態電腦字節碼,並以DBG_END_SEQUENCE BYTE結束。

州機器由五個登記冊組成。 address暫存器表示16位元代碼單元中關聯的insns_item中的指令偏移。 address暫存器從每個debug_info序列開始時從0開始,只能單調增加。 line暫存器表示應與狀態計算機發出的下一個位置表條目關聯的來源線號。它是在序列標頭中初始化的,並且可能會在正方向或負方向上變化,但絕不能小於1source_file暫存器表示行號參考的來源檔案。它被初始化為class_def_itemsource_file_idx的值。其他兩個變量, prologue_endepilogue_begin ,是布爾旗(初始化為false ),表明是否應將下一個發出的位置視為方法序言或結語。狀態計算機還必須在每個暫存器中為DBG_RESTART_LOCAL程式碼追蹤最後一個本機變數的名稱和類型。

標題如下:

姓名格式描述
line_start Uleb128狀態計算機line暫存器的初始值。不代表實際的位置條目。
parameters_size Uleb128編碼的參數名稱的數量。每個方法參數應該有一個,如果有的this ,則不包括實例方法。
parameter_names uleb128p1 [parameters_size]方法參數名稱的字串索引。 NO_INDEX的編碼值表示關聯參數沒有名稱。類型的描述符和簽名是從方法描述符和簽名中暗示的。

位元組代碼值如下:

姓名價值格式論點描述
dbg_end_sequence 0x00 (沒有任何)終止code_item的偵錯資訊序列
dbg_advance_pc 0x01 uleb128 addr_diff addr_diff :加到地址註冊的金額在不發出職位條目的情況下推進地址登記冊
dbg_advance_line 0x02 sleb128 line_diff line_diff :透過在沒有排放職位條目的情況下推進行寄存器
dbg_start_local 0x03 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
register_num :註冊將包含本地
name_idx :名稱的字串索引
type_idx :類型的型別索引
在目前地址引入局部變數。 name_idxtype_idx可能是NO_INDEX ,表示該值未知。
dbg_start_local_extended 0x04 uleb128 register_num
uleb128p1 name_idx
uleb128p1 type_idx
uleb128p1 sig_idx
register_num :註冊將包含本地
name_idx :名稱的字串索引
type_idx :類型的型別索引
sig_idx :類型簽署的字串索引
在目前地址引入具有類型簽名的本地。 name_idxtype_idxsig_idx中的任何一個都可能是NO_INDEX ,表示該值未知。 (但是,如果sig_idx-1 ,則可以使用OPCODE DBG_START_LOCAL更有效地表示相同的資料。)

注意:有關處理簽名的警告,請參閱下面「 dalvik.annotation.Signature 」下的討論。

dbg_end_local 0x05 uleb128 register_num register_num :註冊包含本地的註冊在目前位址上標記目前壽命的局部變數範圍不超出範圍
dbg_restart_local 0x06 uleb128 register_num register_num :註冊至重新啟動在目前地址重新引入局部變數。名稱和類型與指定暫存器中的最後一個本機相同。
dbg_set_prologue_end 0x07 (沒有任何)設定prologue_end狀態機暫存器,表示應將新增的下一個位置條目視為方法序言的結束(方法斷點的適當位置)。 prologue_end暫存器由任何特殊( >= 0x0a )OpCode清除。
dbg_set_epilogue_begin 0x08 (沒有任何)設定epilogue_begin狀態機暫存器,表示應將新增的下一個位置條目視為方法結尾的開始(方法退出前暫停執行的適當位置)。 epilogue_begin暫存器由任何特殊( >= 0x0a )OpCode清除。
dbg_set_file 0x09 uleb128p1 name_idx name_idx :來源檔案名稱的字串索引; NO_INDEX如果未知指示所有後續的行號條目都引用此來源檔案名,而不是code_item中指定的預設名稱
特殊的Opcodes 0x0a…0xff (沒有任何)lineaddress暫存器,排放位置輸入,並清除prologue_endepilogue_begin 。請參閱下文以取得說明。

特殊的Opcodes

具有0x0a0xff (包含)的值的Opcodes少量移動行和address line ,然後發出新的位置表條目。增量的公式如下:

DBG_FIRST_SPECIAL = 0x0a  // the smallest special opcode
DBG_LINE_BASE   = -4      // the smallest line number increment
DBG_LINE_RANGE  = 15      // the number of line increments represented

adjusted_opcode = opcode - DBG_FIRST_SPECIAL

line += DBG_LINE_BASE + (adjusted_opcode % DBG_LINE_RANGE)
address += (adjusted_opcode / DBG_LINE_RANGE)

Annotations_directory_item

從class_def_item引用

出現在資料部分

對齊:4個位元組

姓名格式描述
class_annotations_off單位從文件的開頭偏移到直接在課堂上進行的註釋,或者如果類別沒有直接註釋,則偏移0 。偏移量(如果非零)應為data部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。
fields_size單位該項目註解的欄位計數
Annotated_methods_size單位該項目註釋的方法計數
Annotated_pa​​rameters_size單位此項目註解的方法參數列表
field_annotations field_annotation [fields_size] (可選)相關字段註釋列表。列表的元素必須按field_idx進行越來越多的順序排序。
method_annotations method_annotation [methods_size] (可選)相關方法註釋清單。列表的元素必須依照method_idx進行越來越多的順序排序。
參數_annotations parameter_annotation [parameters_size] (可選)相關方法參數註解清單。列表的元素必須依照method_idx進行越來越多的順序排序。

注意:所有元素的field_idmethod_id實例必須參考相同的定義類別。

field_annotation格式

姓名格式描述
field_idx單位索引到field_ids列表,以註釋字段的身份
Annotations_off單位從文件的開頭偏移到該欄位的註解清單。偏移應為data部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。

method_annotation格式

姓名格式描述
method_idx單位索引索引用於註解的方法的身分的method_ids列表
Annotations_off單位從文件的開頭偏移到該方法的註釋列表。偏移應為data部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。

參數_annotation格式

姓名格式描述
method_idx單位索引到method_ids列表,以指定參數正在註釋的方法的身份
Annotations_off單位從文件的開頭偏移到方法參數的註釋列表。偏移應為data部分中的位置。資料的格式由下面的「 annotation_set_ref_list 」指定。

annotation_set_ref_list

從parameter_annotations_item引用

出現在資料部分

對齊:4個位元組

姓名格式描述
尺寸單位清單的大小,條目
清單annotation_set_ref_item [size]列表的元素

Annotation_set_ref_item格式

姓名格式描述
Annotations_off單位如果沒有對此元素的註釋,則從檔案的開頭偏移到引用的註釋集或0 。偏移量(如果非零)應為data部分中的位置。資料的格式由下面的「 annotation_set_item 」指定。

Annotation_set_item

從Annotations_directory_item,field_annotations_item,method_annotations_item和annotation_set_set_ref_item引用

出現在資料部分

對齊:4個位元組

姓名格式描述
尺寸單位集合的大小,在條目中
條目Annotation_off_item [size]集合的元素。元素必須按type_idx進行越來越多的順序排序。

Annotation_Off_Item格式

姓名格式描述
Annotation_off單位從文件的開頭偏移到註釋。偏移應為data部分中的位置,並且該位置的資料格式由下面的“ annotation_item ”指定。

Annotation_Item

從Annotation_set_item引用

出現在資料部分

對齊:無(位元組對準)

姓名格式描述
能見度Ubyte該註釋的預期可見性(見下文)
註解Encoded_annotation上面的「 encoded_annotation格式」所描述的格式編碼的註解內容上面的「 encoded_value格式」。

可見性值

這些是annotation_itemvisibility欄位的選項:

姓名價值描述
visibility_build 0x00僅打算在建置時間可見(例如,在其他程式碼的彙編過程中)
visibility_runtime 0x01打算在運行時可見
visibility_system 0x02打算在運行時可見,但僅針對基礎系統(而不是常規用戶代碼)

ENCODED_ARRAY_ITEM

從class_def_item引用

出現在資料部分

對齊:無(位元組對準)

姓名格式描述
價值ENCODED_ARRAY代表編碼數組值的字節,以上面的“ encoded_array編碼”下的“ encoded_value格式”指定的格式。

hiddenapi_class_data_item

本節包含有關每個類別使用的限制介面的資料。

注意:隱藏的API功能是在Android 10.0中引入的,僅適用於引導類別路徑中類別的DEX檔案。以下所述的標誌清單可以在Android的未來版本中擴展。有關更多信息,請參閱非SDK介面的限制

姓名格式描述
尺寸單位本節的總尺寸
偏移量uint [] class_idx索引的偏移數組。 index class_idx處的零數組條目意味著該class_idx沒有數據,或所有隱藏的API標誌為零。否則,陣列條目為非零,並且包含從部分開始到此class_idx的隱藏API標誌陣列的偏移。
旗幟uleb128 []每個類別的隱藏API標誌的串聯陣列。下表中描述了可能的標誌值。標誌按與欄位相同的順序進行編碼,方法在類別資料中編碼。

限制標誌類型:

姓名價值描述
白名單0可以自由使用並作為正式記錄的Android框架軟體包索引的一部分來支援的介面。
灰列表1無論應用程式的目標API等級為何,都可以使用的非SDK介面。
黑名單2無論應用程式的目標API等級為何,都無法使用的非SDK介面。存取這些介面之一會導致運行時錯誤
GreyList -Max -O 3除非受到限制,否則可用於Android 8.x及以下的非SDK介面。
GreyList -Max -p 4除非受到限制,否則可用於Android 9.x的非SDK介面。
GreyList -Max -Q 5除非受到限制,否則可用於Android 10.x的非SDK介面。
Greylist -Max -r 6除非受到限制,否則可用於Android 11.x的非SDK介面。

系統註釋

系統註釋用於表示有關類別(以及方法和欄位)的各種反思性資訊。通常僅透過客戶端(非系統)代碼間接存取此資訊。

系統註解在.dex檔案中表示為可見度設定為VISIBILITY_SYSTEM註解。

dalvik.annotation.annotation -default

出現在註解介面中的方法上

每個註釋介面都附加了AnnotationDefault註釋,該介面希望指示預設綁定。

姓名格式描述
價值註解此註解的預設綁定,表示為這種類型的註解。註釋不必包括註釋定義的所有名稱;缺少名稱根本沒有預設值。

dalvik.annotation.closingclass

出現在課堂上

每個類別都附上一個EnclosingClass註釋,定義為另一個類別的成員本身,或是匿名的,而不是在方法主體中定義的(例如,合成的內部類別)。每個具有此註釋的班級也必須具有InnerClass註釋。此外,一類不得具有EnclosingClassEnclosingMethod註解。

姓名格式描述
價值班級最緊密掌握這類的課程

dalvik.annotation.closingMethod

出現在課堂上

每個類別在方法主體內定義的類別的EnclosingMethod方法註釋。每個具有此註釋的班級也必須具有InnerClass註釋。此外,一類不得具有EnclosingClassEnclosingMethod註解。

姓名格式描述
價值方法最緊密掌握這類的方法

dalvik.annotation.innerclass

出現在課堂上

每個類別InnerClass註解都附加在另一個類別定義的詞彙範圍中定義的每個類別。具有此註釋任何類別也必須具有EnclosingClass註解EnclosingMethod註解。

姓名格式描述
姓名細繩最初聲明的此類簡單名稱(不包括任何包裝前綴)。如果此類是匿名的,則名稱為null
AccessFlags整數最初聲明的類別存取標誌(由於來源語言的執行模型與目標虛擬機器之間的執行模型之間的不匹配可能與有效標誌有所不同)

dalvik.annotation.memberClasses

出現在課堂上

MemberClasses註釋附在每個宣布會員類別的類別上。 (成員類別是具有名稱的直接內部類別。)

姓名格式描述
價值班級[]會員類的數組

dalvik.annotation.methodparameters

出現在方法上

注意: Android 7.1之後新增了此註解。它在早期的Android版本上的存在將被忽略。

MethodParameters註解是可選的,可用於提供參數元數據,例如參數名稱和修飾符。

當運行時不需要參數元資料時,可以從方法或建構子中省略註解。 java.lang.reflect.Parameter.isNamePresent()可用於檢查是否存在參數的元數據,並且相關的反射方法(例如java.lang.reflect.Parameter.getName()將在運行時降回預設行為,如果訊息不存在。

當包含參數元資料時,編譯器必須包含產生類別(例如枚舉)的訊息,因為參數元資料包括參數是否是合成的或要求的。

MethodParameters註解僅描述單一方法參數。因此,為了程式碼大小和執行時間效率,為沒有參數的建構函式和方法省略了編譯器的註解。

以下記錄的陣列必須與與該方法關聯的method_id_item dex結構相同,否則在執行時會拋出java.lang.reflect.MalformedParametersException

也就是說: method_id_item.proto_idx > proto_id_item.parameters_off > type_list.size必須與names().lengthaccessFlags().length相同。

由於MethodParameters描述了所有正式方法參數,即使是在原始程式碼中未明確或隱式聲明的那些參數,因此陣列的大小可能與僅基於在原始程式碼中聲明的明確參數的簽章或其他元資料資訊有所不同。 MethodParameters也會不包含有關實際方法簽章中不存在的型別註解接收器參數的任何資訊。

姓名格式描述
名字細繩[]相關方法的形式參數的名稱。數組不得為空,但如果沒有形式參數,則必須為空。如果帶有該索引的正式參數沒有名稱,則數組中的值必須為null。
如果參數名稱字串為空或包含'。','','['或'/',則在運行時將拋出java.lang.reflect.MalformedParametersException
AccessFlags整數[]相關方法的形式參數的存取標誌。數組不得為空,但如果沒有形式參數,則必須為空。
該值有點掩碼,具有以下值:
  • 0x0010:最終,該參數被宣佈為最終
  • 0x1000:合成,參數是由編譯器引入的
  • 0x8000:規定,此參數是合成的,但也暗示語言規範所暗示
如果設定在此群組之外的任何位,則將在執行時拋出java.lang.reflect.MalformedParametersException

dalvik.annotation.Signature

出現在類,字段和方法上

Signature註釋附加到每個類,字段或方法上,該簽名是根據type_id_item表示的更複雜的類型定義的。 .dex格式並未定義簽名格式;它只是為了代表源語言成功實施該語言語義所需的任何簽名。因此,簽章通常不會透過虛擬機器實作來解析(或驗證)。這些簽名只是將其移交給更高級別的API和工具(例如辯論者)。因此,任何使用簽名的用法都應寫成,以免對僅接收有效簽名做出任何假設,從而明確守護自己遇到句法無效的簽名的可能性。

因為簽名字串傾向於具有大量重複的內容,因此Signature註釋被定義為一系列字串,其中重複的元素自然指的是相同的基礎數據,並且簽名被視為陣列中所有字串的串聯。沒有關於如何將簽名拉入單獨的字串的規則;這完全取決於生成.dex檔案的工具。

姓名格式描述
價值細繩[]該班級或成員的簽名,作為一系列要串聯在一起的字串

dalvik.annotation.throws

出現在方法上

Throws註釋附加到每個方法上,該方法被聲明為拋出一種或多種異常類型。

姓名格式描述
價值班級[]拋出的例外類型的數組