1. Introduction
1.绪论
When we compile a .java file, we get a separate class file with a .class extension. The .class file consists of several sections and a constant pool is one of them.
当我们编译一个.java文件时,我们会得到一个单独的扩展名为.class的类文件。.class文件由几个部分组成,常量池是其中之一。
In this quick tutorial, we’re going to explore the details of a constant pool. Also, we’ll see what are types it supports and how it formats the information.
在这个快速教程中,我们将探讨常量池的细节。此外,我们将看到它支持哪些类型,以及它是如何格式化信息的。
2. Constant Pool in Java
2.Java中的常量池
Simply put, a constant pool contains the constants that are needed to run the code of a specific class. Basically, it’s a runtime data structure similar to the symbol table. It is a per-class or per-interface runtime representation in a Java class file.
简单地说,常量池包含运行特定类的代码所需的常量。基本上,它是一个类似于符号表的运行时数据结构。它是Java类文件中每个类或每个界面的运行时表示。
The content of the constant pool consists of symbolic references generated by the compiler. These references are names of variables, methods, interfaces, and classes referenced from the code. The JVM uses them to link the code with other classes it depends on.
常量池的内容包括由编译器生成的符号引用。这些引用是代码中引用的变量、方法、接口和类的名称。JVM使用它们来连接代码和它所依赖的其他类。
Let’s understand the structure of a constant pool using a simple Java class:
让我们用一个简单的Java类来理解常量池的结构。
public class ConstantPool {
public void sayHello() {
System.out.println("Hello World");
}
}
To view the constant pool’s content, we need to first compile the file and then run the command:
要查看常量池的内容,我们需要首先编译文件,然后运行命令。
javap -v name.class
The above command will yield:
上述命令将产生。
#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 indicates the references to the constant pool. #17 is a symbolic reference to the “Hello World” String, #18 is System.out, and #19 is a println. Similarly, #8 highlights that the return type of method is void and #20 is a fully qualified class name.
#n表示对常量池的引用。#17是对“Hello World “字符串的符号引用,#18是System.out,#19是一个println。类似地,#8强调方法的返回类型是void,#20是一个完全合格的类名。
It is important to note that the constant pool table starts from index 1. The index value 0 is regarded as an invalid index.
需要注意的是,常量池表从索引1开始。索引值0被认为是无效的索引。
2.1. Types
2.1.类型
The constant pool supports several types:
常量池支持几种类型。
- Integer, Float: with 32-bit constants
- Double, Long: with 64-bit constants
- String: a 16-bit string constant that points at another entry in the pool which contains the actual bytes
- Class: contains the fully qualified class name
- Utf8: a stream of bytes
- NameAndType: a colon-separated pair of values, first entry represents the name while the second entry indicates the type
- Fieldref, Methodref, InterfaceMethodref: a dot-separated pair of values, first value points at Class entry whereas the second value points as NameAndType entry
What about the other types like boolean, short, and byte? These types are represented as Integer constant in the pool.
其他类型如boolean、short和byte呢?这些类型在池中被表示为Integer常量。
2.2. Format
2.2 格式
Each entry in the table obeys a general format:
表中的每个条目都遵守一个一般的格式。
cp_info {
u1 tag;
u1 info[];
}
The initial 1-byte tag indicates the kind of constant. Once a JVM grabs and intercepts the tags, it knows what follows the tag. Usually, the tag is followed by two or more bytes to carry the information about that constant.
最初的1字节标签表示常量的种类。一旦JVM抓取并拦截了这些标签,它就知道标签后面的内容。通常情况下,标签后面有两个或更多的字节来携带关于该常量的信息。
Let’s look at some of the types and their tag indexes:
让我们看看其中的一些类型和它们的标签索引。
- Utf8: 1
- Integer: 3
- Float: 4
- Long: 5
- Double: 6
- Class reference: 7
- String reference: 8
The constant pool of any class or interface is created only when the JVM has completed its loading.
任何类或接口的常量池只有在JVM完成加载后才会创建。。
3. Conclusion
3.总结
In this quick article, we learned about the constant pool in JVM. We’ve seen that it contains symbolic references that are used to locate the actual objects. Also, we look at how the pool format the information about constants and their types.
在这篇快速文章中,我们了解了JVM中的常量池。我们已经看到,它包含了用于定位实际对象的符号引用。此外,我们还看了池子是如何格式化常量及其类型的信息的。
As always, the code snippet can be found over on Github.
一如既往,代码片段可以在Github上找到over。