java class.類結構.method

  • methods

方法表與field_info中的屬性表結構相同,方法里的代碼,經過編譯成字節碼指令后,存放在方法屬性表集合中一個Code屬性中。與字段表集合相對應,如果父類方法在子類中沒有被重寫,方法表集合中就不會出現來自父類的方法信息。但同樣,有可能會出現由編譯器自動添加的方法,最典型的的類構造器<clinit>方法和實例構造器<init>方法。
重載:java中,重載一個方法,除了要與原方法具有相同的簡單名稱外,還要擁有一個與原方法不同的特征簽名,特征簽名就是一個方法中各個參數在常量池中的字段符號引用的集合,也就是因為返回值不包含在特征簽名中,所以java無法僅靠返回值不同來對一個方法進行重載。

方法訪問標志

方法表結構



  • Code結構
  1. 結構:
    屬性名索引(u2,Code)+屬性值長度(u4)+屬性值
  2. Code屬性值結構
    max_stack(u2)+max_locals(u2)+指令長度(u4)+指令+異常表長度(u2,exception_table_length)+異常表+屬性表數量(u2)+屬性表
    Code屬性表結構
  • 方法表中不一定存在Code屬性

Java程序方法體中的代碼經過Javac編譯后,生成的字節碼指令便會存儲在Code屬性中,但并非所有的方法表都必須存在這個屬性,比如接口或抽象類中的方法就不存在Code屬性

  • max_stack

max_stack是操作數棧深度的最大值,就是方法調用深度,其值與棧幀大小有關,可能類似于max_stack*棧幀大小=棧

  • max_locals

Slot的長度與字節的關系

max_locals代表局部變量表所需的存儲空間,單位是Slot,并不是在方法中用到了多少局部變量,就把這些局部變量所占Slot之和作為max_locals的值,max_locals<=Code的局部變量表長度(local_variable_table_length),是通過局部變量的作用域計算出來的一個最小的Slot值,因為局部變量超出作用域就相當于沒用了,因而可以復用。
max_locals計算

下面是重點:

  • max_stack

最大棧深度,單位是Slot

  • max_locals

最大可能使用的局部變量表的長度,單位是Slot

  • 至少有2種情況可以影響max_locals的值
  1. 方法中的局部變量作用域
    如下
public class TestClass {

   public int inc() {
       {
           int c=1;
           c++;
       }
       int d=2;
       d++;
       return 2;
   }

}

顯然c、d的作用域沒有重合的地方,那么就可以重用。這種方式就可以減少max_locals

  1. 存放臨時數據的Slot
    例如java class.類結構.例子.通過一個帶Exception的方法對其執行步驟進行詳細解釋中,變量表中有3個變量,而實際上max_slots為5
    這種是增加max_locals


  • 異常表結構


根據上面的Exception table,異常表分為
from(start_pc)try開始的位置
to(end_pc)try結束的位置,不包含
target(handler_pc)catch開始的位置
type(catch_type):異常類型,如Class java/lang/Exception表示Exception類型異常,any表示所有類型異常

處理邏輯如下:
如果當字節碼在第start_pc到第end_pc行之間(不包括end_pc)出現了類型為catch_type或其子類的異常,則轉到第handler_pc行繼續處理。當catch_type為0時,代表所有異常。
行的說明:行是字節碼對于方法體開始的偏移量。



  • 異常屬性

與異常表結構區分。
描述的是 throws后面列舉的異常


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。