在了解字符串常量池之前,先看下面一段代码:
String str1 = "hello";
String str2 = "hello";
String str3 = new String("hello");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
输出结果:
true
false
在上面一段代码中可以看出 两个字符序列相同的而不是使用new创建的字符串对象str1 和str2指向的是一个对象,这里就是字符创常量池在起作用。
字符串常量池
字符串对象的创建和和其他对象的创建一样都需要付出昂贵的时间和空间代价,所以JVM为了为了提高性能和减少内存开销,字符串类维护了一个字符串池,每当代码创建字符串常量时,JVM会首先检查字符串常量池。如果字符串已经存在池中,就返回池中的实例引用。如果字符串不在池中,就会实例化一个字符串并放到池中。
java.lang.String.intern() 方法
先来看下java doc中的解释
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String.
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.
All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.
具体作用可以理解为获得在常量池中的符号引用,如果常量池中没有该常量字符串,该方法会将字符串加入常量池。
看下面这段代码
String s1=new String("he")+new String("llo");//1
String s2=new String("h")+new String("ello");//2
String s3=s1.intern();//3
String s4=s2.intern();//4
System.out.println(s1==s3);//5
System.out.println(s1==s4);//6
输出
true
true
在第三行中s1.intern() 在常量池中不存在值为hello的字符串对象,将s1放入常量池,然后返回s1,即s3 = s1
在第四行中,在因为s1已经放入常量池中,所以s2.intern()返回s1,即s4 = s1
在上段代码里的第一行总共创建了几个String对象?
可以参考这篇文章 请别再拿“String s = new String(“xyz”);创建了多少个String实例”来面试了吧
参考文章
https://segmentfault.com/a/1190000009888357#articleHeader3
https://www.zhihu.com/question/55994121/answer/147296098
http://www.importnew.com/10756.html
水平有限,有问题欢迎指出