1. 字面量
字面量就是指由字母、数字等构成的字符串或者数值常量。字面量只可以右值出现,所谓右值是指等号右边的值,
如:int a=1这里的a为左值,1为右值。
在这个例子中1就是字面量。
2. 符号引用
符号引用包括三种类型:
(1)类与接口的全限定名
(2)字段名称与描述符
(3)方法名称与描述符
常量池中的静态信息,只有被加载到内存中后,才被赋予对应的内存地址。此时这些常量池变为运行时常量池,对应的符号引用在程序加载或运行时会被转变为直接引用,也称为动态链接。
3. 字符串常量池
JVM为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。
(1)为字符串开辟一个字符串常量池,类似于缓存区。
(2)创建新的字符串常量时,先从缓存池中查询是否有该字符串缓存。
(3)存在该字符串,返回引用实例,不存在,实例化该字符串并放入池中。
4. 不同种字符串的操作
(1)直接赋值字符串
String test = "test";
创建过程:先到常量池中查询是否有test这个字符串,有则直接返回引用。若没有,则在常量池中创建该值,并返回引用。
(2)通过初始化String对象方式
String s1 = new String("test"); //s1指向内存中的对象引用
创建过程:变量s1会在堆中生成String对象,并在常量池中判断是否已存在test这个字面量,若不存在,则在常量池中生成该字面量。
(3)intern方法
String s1 = new String("test");
String s2 = s1.intern();
创建过程:String中的intern方法是一个native的方法,当调用intern方法时,如果池已经包含一个等于此String对象的字符串
(用equals(oject)方法确定),则返回池中的字符串。
否则,将intern返回的引用指向当前字符串s1(jdk1.6版本需要将
s1复制到字符串常量池里)。
(4)字符串常量池位置
Jdk1.7:有永久代,但已经逐步“去永久代”,字符串常量池从永久代里的运行时常量池分离到堆里。
Jdk1.8及之后:无永久代,运行时常量池在元空间,字符串常量池里依然在堆里。
String s1 = new String("he") + new String("llo");
String s2 = s1.intern();
System.out.println(s1==s2);
// 该段代码共生成了多少个对象?

网友评论