1、介绍
字符串String的创建是很消耗内存的,所以为了提高性能和减少内存的开销,在实例化字符串的时候进行了一些优化。大佬们决定把一些相同的字符串的引用都指向一个字符串,然后就诞生了常量池。
2、具体情况
在下面几个情况,会把一个字符串存在常量池中
-
字面量形式创建字符串对象
JVM首先会对这个字面量进行检查,如果字符串常量池中存在相同内容的字符串对象的引用,则将这个引用返回,否则新的字符串对象被创建,然后将这个引用放入字符串常量池,并返回该引用。由于String字符串的不可变性我们可以十分肯定常量池中一定不存在两个相同的字符串。
String s1 = "aa"; String s2 = "aa"; System.out.println(s1 == s2); //true
-
串未经过变量代表相加
String s1 = "abc"; String s2 = "a" + "bc"; System.out.println(s1 == s2); //true
-
掉用String的intern()函数
调用时会检查字符串常量池是否有相同字符串一样,若有则将字符串常量池中的字符串赋给引用,若无则把自己的对象添加到常量池,并放回此对象的引用,原来对象不变。
String s1 = "aa"; String s2 = new String("aa"); String s3 = s2.intern(); //此时这个s3就指向常量池中的对象 System.out.println( a==s3); //true System.out.println( a==s2.intern()); //true
还有一个情况
-
new创建
当我们使用了new来构造字符串对象的时候,不管字符串常量池中有没有相同内容的对象的引用,新的字符串对象都会被创建。
有个特殊的情况就是“b” + new String(“aa”),此时创建的字符串“aa”也在常量池中,因为new时会先在堆中创建字符串,再添加到常量池中,注意此时堆中的字符串没有被删掉。String a = "baa"; String b = new String("baa"); String c = "b"+new String("aa"); System.out.println(a == b); //false System.out.println(a == c); //false System.out.println(b == c); //false