String和String Pool解析

       本文先說明下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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章