JVM中的常量池簡介
瀏覽人數:571最近更新:
1.簡介
編譯.java
文件時,會得到一個擴展名為.class
的單獨的類文件。 .class
文件由幾個部分組成,並且常量池就是其中之一。
在本快速教程中,我們將探討常量池的詳細信息。另外,我們將看到它支持什麼類型以及如何格式化信息。
2. Java中的常量池
簡而言之,常量池包含運行特定類的代碼所需的常量。基本上,它是類似於符號表的運行時數據結構。它是Java類文件中每個類或每個接口的運行時表示形式。
常量池的內容由編譯器生成的符號引用組成。這些引用是從代碼引用的變量,方法,接口和類的名稱。 JVM使用它們將代碼與它其他依賴的類鏈接。
讓我們使用一個簡單的Java類來了解常量池的結構:
public class ConstantPool {
public void sayHello() {
System.out.println("Hello World");
}
}
要查看常量池的內容,我們需要首先編譯文件,然後運行以下命令:
javap -v name.class
上面的命令將產生:
#1 = Methodref #6.#14 // java/lang/Object."<init>":()V
#2 = Fieldref #15.#16 // java/lang/System.out:Ljava/io/PrintStream;
#3 = String #17 // Hello World
#4 = Methodref #18.#19 // java/io/PrintStream.println:(Ljava/lang/String;)V
#5 = Class #20 // com/baeldung/jvm/ConstantPool
#6 = Class #21 // java/lang/Object
#7 = Utf8 <init>
#8 = Utf8 ()V
#9 = Utf8 Code
#10 = Utf8 LineNumberTable
#11 = Utf8 sayHello
#12 = Utf8 SourceFile
#13 = Utf8 ConstantPool.java
#14 = NameAndType #7:#8 // "<init>":()V
#15 = Class #22 // java/lang/System
#16 = NameAndType #23:#24 // out:Ljava/io/PrintStream;
#17 = Utf8 Hello World
#18 = Class #25 // java/io/PrintStream
#19 = NameAndType #26:#27 // println:(Ljava/lang/String;)V
#20 = Utf8 com/baeldung/jvm/ConstantPool
#21 = Utf8 java/lang/Object
#22 = Utf8 java/lang/System
#23 = Utf8 out
#24 = Utf8 Ljava/io/PrintStream;
#25 = Utf8 java/io/PrintStream
#26 = Utf8 println
#27 = Utf8 (Ljava/lang/String;)V
#n
表示對常量池的引用。 #17是對“Hello World” String
的符號引用,#18是System.out
,而#19是println.
同樣,
#8強調方法的返回類型為void
而#20為完全限定的類名。
重要的是要注意,常量池表從索引1開始。索引值0被視為無效索引。
2.1。種類
常量池支持幾種類型:
-
Integer
,Float
:具有32位常量 -
Double
,Long
:具有64位常量 -
String
:一個16位的字符串常量,指向池中包含實際字節的另一個條目 -
Class
:包含完全限定的類名稱 -
Utf8
:字節流 -
NameAndType
:冒號分隔的一對值,第一個條目表示名稱,第二個條目表示類型 -
Fieldref
,Methodref
,InterfaceMethodref
:點分隔的一對值,第一個值指向Class
條目,而第二個值指向NameAndType
條目
那麼其他類型如boolean
, short
和byte
呢?這些類型在池中表示為Integer
常量。
2.2。格式
表中的每個條目均遵循通用格式:
cp_info {
u1 tag;
u1 info[];
}
最初的1字節標籤指示常量的種類。 JVM抓取並攔截標籤後,便知道標籤後面的內容。通常,標籤後跟兩個或多個字節,以攜帶有關該常數的信息。
讓我們看一些類型及其標籤索引:
-
Utf8
:1 -
Integer
:3 -
Float
:4 -
Long
:5 -
Double
:6 - 班級參考:7
-
String
參考:8
只有在JVM完成加載後,才會創建任何類或接口的常量池。
3.結論
在這篇快速文章中,我們了解了JVM中的常量池。我們已經看到它包含用於定位實際對象的符號引用。此外,我們還將研究常量池如何查看常量池的內容及其類型的信息。
本作品係原創或者翻譯,採用《署名-非商業性使用-禁止演繹4.0國際》許可協議