1. 程式人生 > >jvm虛擬機器 class檔案常量池與執行時常量池

jvm虛擬機器 class檔案常量池與執行時常量池

jvm虛擬機器 class檔案常量池與執行時常量池

class檔案常量池

java檔案編譯後生成class檔案,裡面存有兩部分內容:

  1. 類的版本、欄位、方法、介面等描述資訊。(欄位是指我們平時在介面或類裡宣告的各種變數 int a 等)
  2. 常量池:存放編譯期生成的字面量和符號引用。

class檔案常量池就是指上面描述的class檔案的常量池,其中字面量包括 文字字串如“hello”、宣告為final的常量值等。 符號引用屬於編譯原理方面的東西包括下面三類常量:

  • 類和介面的全限定名
  • 欄位的名稱和描述符
  • 方法的名稱和描述符

執行時常量池

Java程式碼在進行Javac編譯的時候,並不像C和C++那樣有“連線”這一-步驟,而是在;虛擬機器載入Class檔案的時候進行動態連線。也就是說,在Class檔案中不會儲存各個方法、欄位的最終記憶體佈局資訊,因此這些欄位、方法的符號引用不經過執行期轉換的話無法得到真正的記憶體人口地址,也就無法直接被虛擬機器使用。當虛擬機器執行時,需要從常量池獲得對應的符號引用,再在類建立時或執行時解析、翻譯到具體的記憶體地址之中。class檔案常量池將在類載入後進入方法區的執行時常量池。執行時常量池內容包括:

  1. class檔案常量池
  2. class檔案常量池裡面的符號引用翻譯出的直接引用

區別:
java虛擬機器對class檔案的每一部分(包括class常量池)都有嚴格規定,每個位元組用於儲存哪種資料等。但是對於執行時常量池java虛擬機器規範沒有做任何細節的要求,不過一般來說除了儲存class檔案常量池的符號引用,還會儲存翻譯出的直接引用。
執行時常量池相對class檔案常量池具備動態性,也就是並非只有class檔案的常量池的內容才能進入方法區的執行時常量池,執行期間也可以將新的常量放入池中,比如我部落格裡寫過的String.intern()方法