国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java class文件格式之屬性詳解_動力節點java學院整理

Java class文件格式之屬性詳解_動力節點java學院整理

2020-11-17 11:01動力節點 Java教程

這篇文章主要介紹了Java class文件格式之屬性詳解,需要的朋友可以參考下

code屬性

code屬性是方法的一個最重要的屬性。 因為它里面存放的是方法的字節碼指令, 除此之外還存放了和操作數棧,局部變量相關的信息。 所有不是抽象的方法, 都必須在method_info中的attributes中有一個code屬性。下面是code屬性的結構, 為了更直觀的展示code屬性和method_info的包含關系, 特意畫出了method_info:

Java class文件格式之屬性詳解_動力節點java學院整理

下面依次介紹code屬性中的各個部分。

attribute_name_index指向常量池中的一個constant_utf8_info , 這個constant_utf8_info 中存放的是當前屬性的名字 “code” 。

attribute_length給出了當前code屬性的長度(不包括前六字節)。

max_stack 指定當前方法被執行引擎執行的時候, 在棧幀中需要分配的操作數棧的大小。

max_locals指定當前方法被執行引擎執行的時候, 在棧幀中需要分配的局部表量表的大小。注意, 這個數字并不是局部變量的個數, 因為根據局部變量的作用域不同, 在執行到一個局部變量以外時, 下一個局部變量可以重用上一個局部變量的空間(每個局部變量在局部變量表中占用一個或兩個slot)。 方法中的局部變量包括方法的參數, 方法的默認參數this, 方法體中定義的變量, catch語句中的異常對象。 關于執行引擎的相關內容會在后面的博客中講到。

code_length指定該方法的字節碼的長度, class文件中每條字節碼占一個字節。

code存放字節碼指令本身, 它的長度是code_length個字節。

exception_table_length 指定異常表的大小

exception_table就是所謂的異常表, 它是對方法體中try-catch_finally的描述。 exception_table可以看做是一個數組, 每個數組項是一個exception_info結構, 一般來說每個catch塊對應一個exception_info,編譯器也可能會為當前方法生成一些exception_info。 exception_info的結構如下(為了直觀的顯示exception_info, exception_table和code屬性的關系, 畫出了code屬性,的話讀者就會更清楚各個數據項之間的位置關系和包含關系):

Java class文件格式之屬性詳解_動力節點java學院整理

下面講解exception_info中的各個字段的意思。

start_pc是從字節碼(code屬性中的code部分)起始處到當前異常處理器起始處的偏移量。

end_pc是從字節碼起始處到當前異常處理器末尾的偏移量。

handler_pc是指當前異常處理器用來處理異常(即catch塊)的第一條指令相對于字節碼開始處的偏移量。

catch_type是一個常量池索引, 指向常量池中的一個constant_class_info數據項, 該數據項描述了catch塊中的異常的類型信息。這個類型必須是java.lang.throwable的或其子類。

所以可以總結, 一個異常處理器(exception_info)的意思是: 如果偏移量從start_pc到end_pc之間的字節碼出現了catch_type描述的類型的異常, 那么就跳轉到偏移量為handler_pc的字節碼處去執行。如果catch_type為0, 就代表不引用任何常量池項(再回顧一下, 常量池中的項是從1開始計的), 那么這個exception_info用于實現finally子句。

我們一直在介紹code屬性, 只不過剛才進行了一個小插曲, 介紹了code屬性中的exception_table中的exception_info的詳細信息。 下面我們繼續介紹code 屬性中的其他信息, 希望讀者不要被繞暈了 : )

attributes_count 表示當前code 屬性中存在的其他屬性的個數。 現在我們知道, class中的屬性, 不僅會出現在頂層的class中, 會存在field_info中, 會存在method_info中, 甚至還會出現在屬性中。 

attributes可以看做是一個數組, 里面存放了code屬性中的其他屬性。 code 屬性中可以出現的其他屬性有linenumbertable和localvariabletable 。 這兩個屬性會在下面介紹。

linenumbertable屬性

linenumbertable屬性存在于code屬性中, 它建立了字節碼偏移量到源代碼行號之間的聯系。 這個屬性是可選的, 編譯器可以選擇不生成該屬性。下面是該屬性的結構(同樣給出了全局的位置關系,linenumbertable在圖的右下角部分):

Java class文件格式之屬性詳解_動力節點java學院整理

由于這個屬性并不是重點, 我們在此簡單的講述。 

每個linenumbertable中的line_number_table部分, 可以看做是一個數組, 數組的每項是一個line_number_info , 每個line_number_info 結構描述了一條字節碼和源碼行號的對應關系。 其中start_pc是這個line_number_info 描述的字節碼指令的偏移量, line_number是這個line_number_info 描述的字節碼指令對應的源碼中的行號。可以看出, 方法中的每條字節碼都對應一個line_number_info , 這些line_number_info 中的line_number可以指向相同的行號, 因為一行源碼可以編譯出多條字節碼。

localvariabletable屬性 

localvariabletable 屬性建立了方法中的局部變量與源代碼中的局部變量之間的對應關系。 這個屬性存在于code屬性中。 這個屬性是可選的, 編譯器可以選擇不生成這個屬性。該屬性的結構如下:(同樣給出了全局的位置關系圖,localvariabletable 在該圖的右下角 )

Java class文件格式之屬性詳解_動力節點java學院整理

由于這個屬性相對不那么重要, 這里只是大概講解一下。

每個localvariabletable 的local_variable_table部分可以看做是一個數組, 每個數組項是一個叫做local_variable_info的結構, 該結構描述了某個局部變量的變量名和描述符, 還有和源代碼的對應關系。下面講解local_variable_info的各個部分:

start_pc是當前local_variable_info所對應的局部變量的作用域的起始字節碼偏移量;

length是當前local_variable_info所對應的局部變量的作用域的大小。 也就是從字節碼偏移量start_pc 到start_pc+length就是當前局部變量的作用域范圍;

name_index指向常量池中的一個constant_utf8_info, 該constant_utf8_info描述了當前局部變量的變量名;

descriptor_index指向常量池中的一個constant_utf8_info, 該constant_utf8_info描述了當前局部變量的描述符;

index描述了在該方法被執行時,當前局部變量在棧幀中局部變量表中的位置。 

由此可知, 方法中的每個局部變量都會對應一個local_variable_info 。 

exceptions屬性

首先需要說明, exceptions屬性不是存在于code屬性中的, 它存在于method_info中的attributes中。 和code屬性是平級的。 這個屬性描述的是方法聲明的可能會拋出的異常, 也就是方法定義后面的throws聲明的異常列表, 請不要和上面提到的異常處理器混淆。 異常處理器描述了方法的字節碼如何處理異常, 而exceptions屬性描述方法可能會拋出哪些以異常。下面講解exceptions屬性的結構(左下角為exceptions屬性):

Java class文件格式之屬性詳解_動力節點java學院整理

下面講解exceptions屬性中的信息。 

attribute_name_index和attribute_length就不多說了, 和其他屬性是一樣的。 

number_of_exceptions是該方法要拋出的異常的個數。 

exceptions_index_table可以看做一個數組, 這個數組中的每一項占兩個字節, 這兩個字節是對常量池的索引, 它指向一個常量池中的constant_class_info。 這個constant_class_info描述了一個被拋出的異常的類型。 

總結

到此為止, 和方法相關的屬性就介紹完了。 這篇博客講解的內容相對比較復雜。 下面以一個實例進行驗證, 實例代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.bjpowernode.test;
public class test {
  public void test() throws exception{
    int localvar = 0;
    try{
      class.forname("com.bjpowernode.test.person");
    }catch(classnotfoundexception e){
      throw e;
    }finally{
      system.out.println(localvar);
    }
  }
}

反編譯后的test方法部分(省略了常量池等信息):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public void test() throws java.lang.exception;
 flags: acc_public
 exceptions:
  throws java.lang.exception
 code:
  stack=2, locals=4, args_size=1
    0: iconst_0
    1: istore_1
    2: ldc      #18         // string com.bjpowernode.test.person
    4: invokestatic #20         // method java/lang/class.forname:(ljava/lang/string;)ljava/lang/class;
    7: pop
    8: goto     24
   11: astore_2
   12: aload_2
   13: athrow
   14: astore_3
   15: getstatic   #26         // field java/lang/system.out:ljava/io/printstream;
   18: iload_1
   19: invokevirtual #32         // method java/io/printstream.println:(i)v
   22: aload_3
   23: athrow
   24: getstatic   #26         // field java/lang/system.out:ljava/io/printstream;
   27: iload_1
   28: invokevirtual #32         // method java/io/printstream.println:(i)v
   31: return
  exception table:
    from  to target type
      2   8  11  class java/lang/classnotfoundexception
      2  14  14  any
  linenumbertable:
   line 7: 0
   line 11: 2
   line 13: 8
   line 15: 12
   line 16: 14
   line 17: 15
   line 18: 22
   line 17: 24
   line 20: 31
  localvariabletable:
   start length slot name  signature
       0   32   0 this  lcom/bjpowernode/test/test;
       2   30   1 localvar  i
      12    2   2   e  ljava/lang/classnotfoundexception;

結合上面的講解和圖解, 再分析反編譯的結果, 就一目了然了: 所有的結果是一個method_info, method_info開始處是訪問標志信息。 然后是method_info的 exceptions屬性 , exceptions屬性屬性下面是code屬性, code屬性中又包括字節碼, 異常處理器 ,linenumbertable屬性和localvariabletable 屬性。 

所以會直接或間接的和method_info有聯系, 最后給出一張全局圖, 這樣的話, 讀者就比較明確, 一個完整的方法, 是如何在class文件中描述的,由于考慮到復雜性, 這些屬性或其他數據項中, 對常量池的引用均未畫出:

Java class文件格式之屬性詳解_動力節點java學院整理

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精品久久久久久久久久久久久 | 黄工厂精品免费观看 | 午夜精品久久久久久久星辰影院 | 91五月天| 亚洲淫视频 | 精品一区二区电影 | 亚洲九九 | 国产一区二区视频在线观看 | 国语av在线| 日日干狠狠干 | 久久久久久久久久久免费 | 国产亚洲精品女人久久久久久 | 欧洲精品码一区二区三区免费看 | 91免费黄色片 | 中文字幕66页 | 毛片免费毛片一级jjj毛片 | 欧美成年人网站 | 欧美日韩成人 | 国外成人在线视频网站 | 婷婷综合久久 | 久久久久久久久久久久国产精品 | 狠狠干美女 | 国产精品久久天天躁 | 综合伊人久久 | 欧美在线亚洲 | 瑟瑟视频在线观看 | 日本动漫一区 | 亚洲激情视频在线播放 | 免费观看电视在线高清视频 | 日韩欧美一级片 | 日韩电影中文字幕 | 在线国产一区 | 在线观看成人 | 91aiai| 黄色一级网站视频 | 国产精品激情 | 91视频免费播放 | 亚洲综合大片69999 | 久草电影网| 午夜在线小视频 | 在线播放一区 |