本文先說明下String和String Pool的概念,然後再結合幾個常見的例子來說明下String和String Pool的一些特性,最後再總結下這幾個例子所得出的規律。
1、不可變的String
String的底層實際上是使用private final char[] value來實現字符串的存儲的,就是說String對象一旦創建之後,就不能再修改這個對象存儲的字符串內容。正因爲如此,也說String類是不可改變的。
2、什麼是String Pool
在JVM中存放着一個字符串池,其中保存着很多String對象,這些對象可以被共享使用。當以字符串直接創建String對象時,會首先在字符串池中查找是否存在該常量。如果不存在,則在String Pool中創建一個,然後將其地址返回。如果在String Pool中查詢到已經存在該常量,則不創建對象,直接返回這個對象地址。
3、String的創建
有了以上兩個概念,就可以說說String的創建了。String主要有兩種創建方式,如下:
String str1 = new String(“abc”);
String str2 = “abc”;
雖然兩個語句都是返回一個String對象的引用,但是JVM對這兩種創建的方式是不一樣的。對於第一種,JVM會在內部維護的String Pool中存放一個”abc”的對象,並且在heap中創建一個String對象,然後將該heap中的對象的引用返回給用戶。第二種,JVM首先會在String Pool中查找是否存在”abc”對象,如果已經有則不創建,沒有的話則在String Pool中創建一個對象。
有了以上概念,列一個經常考的面試題:
String s1 = new String(“abc”);
String s2 = new String(“abc”);
上面創建了幾個String對象?(3個)
從一個博文裏面列出下面6個題,檢查下這部分的題目是否已經徹底掌握。
public class Test1 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = new String("abc");
System.out.println(s1 == s2);
}
}
public class Test2 {
public static void main(String[] args) {
String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2);
}
}
public class Test3 {
public static void main(String[] args) {
String s1 = "abc";
String s2 = "ab" + "c";
System.out.println(s1 == s2);
}
}
public class Test4 {
public static void main(String[] args) {
String s = "a";
String s1 = "abc";
String s2 = s + "bc";
System.out.println(s1 == s2);
}
}
public class Test5 {
public static void main(String[] args) {
String s1 = "ab";
String s2 = "ab" + getString();
System.out.println(s1 == s2);
}
private static String getString(){
return "c";
}
}
public class Test6 {
public static void main(String[] args) {
String s = "a";
String s1 = "abc";
String s2 = s + "bc";
System.out.println(s1 == s2.intern());
}
}
答案:
1、false 2、false 3、true 4、false 5、false 6、true
從上面6道題的結果分析,得出如下結論:
1、單獨使用””引號創建的字符串都是常量,編譯期就已經確定存儲到String Pool中。
2、使用new String(“”)創建的對象會存儲到heap中,是運行期新創建的。
3、使用只包含常量的字符串連接符如”aa”+”bb”創建的也是常量,編譯期就能確定已經存儲到String Pool中。
4、使用包含變量的字符串連接如”aa”+s創建的對象是運行期才創建的,存儲到heap中。
5、運行期調用String的intern()方法可以向String Pool中動態添加對象。
參考:http://www.cnblogs.com/kkgreen/archive/2011/08/24/2151450.html