在非常简单的HelloWorld应用程序上运行javap时,我对常量池周围的输出有些困惑。

测试代码

public class TestClass {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

Javap -c-详细输出(已删除)
// 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”常量 push 堆栈,但是const#23似乎保留了实际值。我想我对#(数字)出现在打印输出的右侧时的含义有些困惑。

Oracle/Sun's man page for javap还有很多不足之处。

最佳答案

您所有的classinterfacefield名称和string常量都进入java 常量池

根据VM Spec(http://java.sun.com/docs/books/jvms/second_edition/html/ClassFile.doc.html):



因此,就常量池而言,可以将以下内容视为:

const #22 = String      #23;    //  hello world
const #23 = Asciz       hello world;

#22(索引22)处的值为String类型,其值为null终止的c字符串(Asciz)hello world位于索引23处。

关于java - 了解常量池的javap输出,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5546280/

10-12 00:25
查看更多