1. 字符串常量池
讨论版本为1.8,从1.7开始字符串常量池在堆区,之前在perm
。参考美团技术团队 可能如果常量池中存在当前字符串, 就会直接返回当前字符串
一小句描述不准确,容易引起歧义。
1.1. 字符串常量池为什么在堆中:
perm区比较小,默认只有4M,频繁调用intern()
方法会导致outofMemory
,再者在堆区,新对象intern
到常量池采用直接存储引用,不用再复制对象,性能更好。
1.2. 几个相关操作
=
创建字符串从常量池取,没有则直接存储到常量池。
new String("str")
创建将
"str"
字符串放入常量池,然后在堆区新建一个对象,两个对象不同。String b= a.intern()
字符串对象
a
如果已经存在常量池,返回的b
是常量池中对应的字符串(可查看源码注释);1
2
3
4
5
6
7
8
9// 创建两个对象,一个在常量池,一个是堆区,堆区中的给a
String a=new String("1");;
System.out.println("a: "+System.identityHashCode(a));
// intern时常量池已经存在,返回常量池中的给b,b!=a
String b=a.intern();
System.out.println("b: "+System.identityHashCode(b));
// 从常量池取
String c="1";
System.out.println("c: "+System.identityHashCode(c));如果没有,则将a对象的引用存入常量池,然后返回的b是a的引用(因为都在堆区,1.7之前就是复制到常量池)。
1
2
3
4
5
6
7String s3 = new String("1") + new String("1");
System.out.println("s3: "+System.identityHashCode(s3));
// 将堆区11对象放入常量池,1.7+直接放引用
s3.intern();
// 从常量池取,s4==s3。
String s4 = "11";
System.out.println("s4: "+System.identityHashCode(s4));
赏
使用支付宝打赏
使用微信打赏
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章