目前我正在试图深入挖掘Java虚拟机的规范。 我一直在阅读里面的JVM在线预订 ,并有一个混乱的抽象,我似乎无法把握:常量池。 这里是从书中摘录:
对于它加载每个类型,Java虚拟机必须保存一个常量池。 常量池是有序集合由类型使用的常数,包括文本(字符串,整数和浮点常量)和符号引用类型,字段和方法。 在常量池中项是由索引引用,一个数组元素很像。 因为它拥有所有类型,字段和一个类型使用方法的符号引用,常量池起着Java程序的动态链接核心作用
我有一般以上和CP几个问题:
- 是CP位于
.class
为每种类型的文件? - 什么是笔者的“符号引用”是什么意思?
- 什么是常量池中的宗旨,用简单的英语?
我想了解框架是如何使用的示意图,将有助于构建。
的帧是其中操作数(操作指令)驻留而且那里的动态链接发生。 这是一条捷径,可以这么说,使用常量池跟踪之类的,它的成员。
每帧包含到运行时常量池的参考。 参考点为类的方法的常量池该帧被执行。 该参考,有助于支持动态链接。
C / C ++代码通常编译成目标文件然后将多个目标文件被链接在一起以产品可用伪影,例如可执行文件或DLL。 过程中每个目标文件链接阶段符号引用被替换为相对于最终的可执行的实际存储器地址。 在Java这个链接阶段在运行时动态完成的。
当Java文件编译,变量和方法的所有引用都存储在类的常量池作为一个象征性的参考。 一个符号引用是一个逻辑引用不是实际指向的物理存储器位置的引用。
这里是一个链接詹姆斯花开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
这里是常量池引用。 #2
是一个象征性的参考System.out
领域, #3
是Hello, world!
串和#4
是一个符号参照PrintStream.println(String)
方法。
正如你所看到的,符号引用不只是名字-例如,象征性的参考方法还包含有关其参数(信息Ljava/lang/String;
)和返回式( V
意味着void
)。
您可以通过运行检查一类的常量池javap -verbose
该类。
什么是常量池中的宗旨,用简单的英语?
该CP是一个存储区非常独特的恒定值存储,以减少冗余:
System.err.println("Hello");
System.out.println("Hello");
在CP只有一个String对象“你好”,并在两行相同的编译器的替代品。 你的.class文件只包含一个字符串你好。 (这同样适用其它类型的)。
是CP位于每种类型的.class文件?
是的,看看这里: http://en.wikipedia.org/wiki/Java_class_file
让给实例首先要了解什么字符串常量池的意思
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
这里发生了什么一步一步
被调用时JVM 1-类被装载。
2- JVM将查找程序中的所有字符串文字。
3-首先,它找到的变量s它指的是文字“普拉萨德”,它会在内存中创建
4-一种用于文字“普拉萨德”参考将被放置在字符串常量池存储。
5-然后它找到另一个变量S2,其指的是同一字符串文字“普拉萨德”。
现在,JVM已经找到一个字符串“普拉萨德”,这两个变量s和S2西港岛线是指同一个对象,即“普拉萨德”。
我希望这是有益的
阅读更多http://www.journaldev.com/797/what-is-java-string-pool