在一个非常简单的 HelloWorld 应用程序上运行 javap 时,我对常量池周围的输出有些困惑。
测试代码
public class TestClass {
public static void main(String[] args) {
System.out.println("hello world");
}
}
Javap -c -verbose 输出(截断)
// Header + consts 1..22 snipped
const #22 = String #23; // hello world
const #23 = Asciz hello world;
public static void main(java.lang.String[]);
Signature: ([Ljava/lang/String;)V
Code:
Stack=2, Locals=1, Args_size=1
0: getstatic #16; //Field java/lang/System.out:Ljava/io/PrintStream;
3: ldc #22; //String hello world
5: invokevirtual #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
8: return
// Debug info snipped
}
好的,所以在第 3 行,我们看到通过 #22 将“hello world”常量插入堆栈,但 const #23 似乎保留了实际值。我想当 #(number) 出现在打印输出的右侧时,我对它的含义有些困惑。
Oracle/Sun's man page for javap有很多不足之处。
最佳答案
你所有的 class
、interface
、field
名称和 string
常量都进入 java constant游泳池。
根据 VM 规范 (http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):
The constant_pool is a table of structures (§4.4) representing various string constants, class and interface names, field names, and other constants that are referred to within the ClassFile structure and its substructures. The format of each constant_pool table entry is indicated by its first "tag" byte. The constant_pool table is indexed from 1 to constant_pool_count-1.
所以就常量池而言,如下所示:
const #22 = String #23; // hello world
const #23 = Asciz hello world;
#22 处的值(索引 22)是 String
类型,其值为以空结尾的 c 字符串 (Asciz) hello world
位于索引 23。
关于java - 了解常量池的 javap 输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5546280/