字符串常量池
目录
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());