天天看點

正确使用String類的幾點注意

java.lang.String類對大家來說最熟悉不過了,我們寫java程式很少能不用String的。本文講述如何正确的使用String,内容主要涉及初始化、串聯和比較等操作。

    首先我們必須清楚的一點是String類是final類型的,是以你不可以繼承這個類、不能修改這個類。我們使用String的時候非常簡單,通常都是String s = "hello",但是Java API中同時提供了一個構造函數為String(String s),是以你也可以這樣使用String s = new String("hello"),對于後面這樣初始化一個String的方式是不推薦的,因為new操作符意味着将會在heap上生成一個新的對象,如果這樣的操作發生在一個循環中,那麼代價是慘重的。比如

for (int i = 0; i < 1000; i++)

  {

   String s = new String("hello");   }

這将會建立1000個String類型的對象,由于String類是final的,是以這樣的操作事實上是每次都生成了一個新的String對象的。如果你使用String s = "hello";那麼就可以實作複用了,為什麼可以複用呢,下面會有解釋。

    當我們使用"+"實作串聯操作的時候,比如String s = "hello"+"world";其實是通過StringBuffer類的append()方法實作的,最後傳回String給s。如果有興趣的話,你可以寫一個簡單的例子,然後用javap看看虛拟機是如何工作的。在使用串聯的時候我們同樣應該注意String是final類,如果你需要多次串聯比如:

String sql = "xxx";

sql = "xxxx";

sql = "ssssss";

那麼為了提高效率節省空間,我們應該自己用StringBuffer來替代"+";

    通常對String的比較有兩種情況,一個是使用==,另一個是使用equals()方法,注意==是對對象的位址進行比較的,而String中的equals()方法是覆寫了Object類的方法,并且實作為對String對象的内容的比較。是以String s1 = new String("hello");String s2 = new String("hello"),我們對s1和s2進行上述比較的時候,前者應該傳回false,因為使用new生成的是兩個不同的對象。後者應該傳回true因為他們的内容是一樣的,都是"hello"。那麼如果我們還有一個String s3 = "hello";他和s1的比較應該是什麼樣子的呢,答案是s1==s3為false,equals的比較位true。事實上String類是維持着一個String池的,這個池初始化為空的,當我們String x = "hello"的時候,hello就會被放入這個池中,當我們再次String y = "hello"的時候,他首先去檢查池中是否存在一個和hello内容一樣的對象,如果存在的話就會把這個引用傳回給y,如果不存在的話,就會建立一個并放入到池中。這樣就實作了複用。在String有一個方法intern()他可以把String的對象放入到池沖并傳回池中的對象。如果我們對s1(String s1 = new String("hello"))調用intern,s1 = s1.intern()這時候,我們再把s1和s3進行“==”的判斷,你會發現結果傳回true! 看下面的例子

public class StringTest {



	public static void main(String[] args) {

		String s1 = "hello";

		String s2 = new String("hello");

		String s3 = new String("hello");

		testString(s1, s2, s3);

		s2 = s2.intern();

		System.out.println("after s2.intern");

		testString(s1, s2, s3);

	}



	private static void testString(String s1, String s2, String s3) {

		System.out.println("s1 = s2 is " + (s1 == s2));

		System.out.println("s2 = s3 is " + (s2 == s3));

		System.out.println("s1.equals(s2) is " + s1.equals(s2));

		System.out.println("s2.equals(s3) is " + s2.equals(s3));

		

	}

	/*

	 * 輸出結果為 

	 * s1 = s2 is false 

	 * s2 = s3 is false 

	 * s1.equals(s2) is true

	 * s2.equals(s3) is true 

	 * after s2.intern 

	 * s1 = s2 is true 

	 * s2 = s3 is false

	 * s1.equals(s2) is true 

	 * s2.equals(s3) is true

	 * 

	 */

}