拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 JVM中的常量池简介

JVM中的常量池简介

白鹭 - 2021-11-24 329 0 0

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。种类

常量池支持几种类型:

  • IntegerFloat :具有32位常量
  • DoubleLong :具有64位常量
  • String :一个16位的字符串常量,指向池中包含实际字节的另一个条目
  • Class :包含完全限定的类名称
  • Utf8 :字节流
  • NameAndType :冒号分隔的一对值,第一个条目表示名称,第二个条目表示类型
  • FieldrefMethodrefInterfaceMethodref :点分隔的一对值,第一个值指向Class条目,而第二个值指向NameAndType条目

那么其他类型如booleanshortbyte呢?这些类型在池中表示为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中的常量池。我们已经看到它包含用于定位实际对象的符号引用。此外,我们还将研究常量池如何查看常量池的内容及其类型的信息。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *