Java常量池的目的是什么?

我目前正在深入研究Java虚拟机的规范。 我一直在网上阅读JVM书籍 ,有一个令人困惑的抽象,我似乎无法把握:常量池。 这里是这本书的摘录:

对于加载的每种types,Java虚拟机必须存储常量池。 常量池是types常量的有序集合,包括文字(string,整数和浮点常量)以及对types,字段和方法的符号引用。 常量池中的条目被索引引用,就像数组中的元素一样。 由于它拥有对types使用的所有types,字段和方法的符号引用,所以常量池在Java程序的dynamic链接中起着核心作用

关于上述和CP总体上我有几个问题:

  1. CP是否位于每个types的.class文件中?
  2. 作者所说的“象征性的参考”是什么?
  3. 常量池的目的是什么,用简单的英语?

我觉得理解框架如何使用图表构build会有所帮助。

在这里输入图像说明

该帧是操作数(操作指令)所在的位置,也是dynamic链接发生的地方。 这可以说是一个简短的方法,用常数池来跟踪class级和成员。

每个框架都包含对运行时常量池的引用。 该引用指向正在为该帧执行的方法的类的常量池。 此引用有助于支持dynamic链接。

通常将C / C ++代码编译为一个目标文件,然后将多个目标文件链接在一起以产生可用的工件,如可执行文件或DLL。 在链接阶段,每个目标文件中的符号引用被replace为相对于最终可执行文件的实际内存地址。 在Java中,这个链接阶段是在运行时dynamic完成的。

编译Java文件时,对variables和方法的所有引用都将作为符号引用存储在类的常量池中。 符号引用是逻辑引用,而不是实际指向物理内存位置的引用。

这里是一个链接到James Blooms JVM内部的更多细节。

常量池是.class文件(及其内存中表示)的一部分,它包含运行该类代码所需的常量。

这些常量包括程序员指定的文字和编译器生成的符号引用。 符号引用基本上是从代码引用的类,方法和字段的名称。 JVM使用这些引用将您的代码链接到依赖的其他类。

例如下面的代码

 System.out.println("Hello, world!"); 

产生以下字节码( javap输出)

 0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream; 3: ldc #3; //String Hello, world! 5: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 

#n这里是对常量池的引用。 #2System.out字段的符号引用, #3Hello, world! string和#4是对PrintStream.println(String)方法的符号引用。

正如您所看到的,符号引用不仅仅是名称 – 例如,对该方法的符号引用还包含有关其参数( Ljava/lang/String; )和返回types( V表示void )的信息。

您可以通过为该类运行javap -verbose来检查类的常量池。

常量池的目的是什么,用简单的英语?

CP是一个非常独特的存储区域,常量值被存储以减less冗余:

 System.err.println("Hello"); System.out.println("Hello"); 

在CP中,只有一个String对象“Hello”,编译器将两行replace为相同的引用。 您的.class文件只包含一个Hellostring。 (其他types相同)。

CP是否位于每个types的.Class文件中?

是的,看这里: http : //en.wikipedia.org/wiki/Java_class_file

先给示例先了解一下String常量池的含义

  public class StringConstantPool { public static void main(String[] args) { String s = "prasad"; String s2 = "prasad"; System.out.println(s.equals(s2)); System.out.println(s == s2); } } 

输出将是

 true true 

这里发生的一步一步

1-当JVM被调用时,该类被加载。

2- JVM将查找程序中的所有string文字。

3-首先find引用文字“prasad”variabless ,并在内存中创build它

4-string“prasad”的引用将被放置在string常量池内存中。

5-然后它find另一个引用相同的string“prasad”的 variabless2

现在JVM已经find了string“prasad”variabless和s2都会引用同一个对象,即“prasad”

在这里输入图像说明

我希望这会有所帮助

阅读更多http://www.journaldev.com/797/what-is-java-string-pool