字符串常量池

目录

Java字符串常量池

本文讨论的是JDK8及之后的版本

内存模型的变化

jdk8之后字符串常量池从Perm区转移到堆中

intern机制的变化

如果字符串常量池中存在(StringTable在比较时equals返回true),则返回该字符串对象地址;

如果字符串常量池中不存在,则返回调用intern的字符串对象在堆中的地址,达到复用该对象

字符串常量池的添加方式

通过双引号字符串声明添加

//创建一个对象
String s = "test";
//创建hello,world两个字符串常量池中对象,两个栈中中间变量,一个堆中最终变量"helloworld",注意此字符串不在常量池中
String s = new String("hello") + new String("world"); 

通过intern方法添加

//常量池不存在时
String s = new String("hello") + new String("world"); 
s.intern();
assert s == s.intern();
String s1 = "helloworld";
assert s == s1;
//常量池存在时
String s = new String("hello") + new String("world"); 
String s1 = "helloworld";
s.intern();
assert s.intern()==s1;
assert s != s1;

注意事项

一些由虚拟机创建的已经存在于字符串常量池中的字符串对象如"java",“11"等在使用引用相等时应予以考虑

如以下示例:

//原因是"11"已经提前创建了
String s = new String("1") + new String("1");
s.intern();
String s1 = "11";
assertNotSame(s, s1);
assertNotSame(s, s.intern());