[轉]通過六個題目徹底掌握String

(轉載地址:http://uule.iteye.com/blog/1343458)

Java中String類由於其特殊性(不變類),幾乎是筆試面試中的必考題,當然有些題目其實沒啥意思,不過關鍵是要通過題目掌握原理性的東西。下面六道題目,如果您全部做對了,且明白其所以然,那麼Java中的關於String的筆試面試題應該難不到你了。也許您覺得我說的有點過了,然而徹底明白這些題目,對理解String類還是很有好處的。
寫出下面各題的打印輸出的結果:

1

public static void main(String[] args){
	String a = "a1";
	String b = "a" + 1;
	System.out.println(a==b);
}

2

public static void main(String[] args){
	String a = "ab";
	String bb = "b";
	String b = "a" + bb;
	System.out.println(a==b);
}

3

public static void main(String[] args){
	String a = "ab";
	final String bb = "b";
	String b = "a" + bb;
	System.out.println(a==b);
}

4

public static void main(String[] args){
	String a = "ab";
	final String bb = getBB();
	String b = "a" + bb;
	System.out.println(a==b);
}
private static String getBB() { return "b"; }

5

private static String a = "ab";
public static void main(String[] args){
	String s1 = "a";
	String s2 = "b";
	String s = s1 + s2;
	System.out.println(s == a);
	System.out.println(s.intern() == a);
}

6

private static String a = new String("ab");
public static void main(String[] args){
	String s1 = "a";
	String s2 = "b";
	String s = s1 + s2;
	System.out.println(s == a);
	System.out.println(s.intern() == a);
	System.out.println(s.intern() == a.intern());
}

答案:

1)true

要說明一點:當兩個字符串字面值連接時(相加),得到的新字符串依然是字符串字面值,保存在常量池中。

2)false

當字符串常量與String類型變量連接時,得到的新字符串不再保存在常量池中,而是在堆中新建一個String對象來存放。很明顯常量池中要求的存放的是常量,有String類型變量當然不能存在常量池中了。

3)true

注意此題與上一題的區別,此處是字符串字面值與String類型常量連接,得到的新字符串依然保存在常量池中。

4)false

此題中第條語句:final String bb = getBB();其實與final String bb = new String(“b”);是一樣的。也就是說return “b”會在堆中創建一個String對象保存”b”,雖然bb被定義成了final。可見並非定義爲final的就保存在常量池中,很明顯此處bb常量引用的String對象保存在堆中,因爲getBB()得到的String已經保存在堆中了,final的String引用並不會改變String已經保存在堆中這個事實。

5)false,true

可能很多人對intern()這個函數不瞭解。JDK API文檔中對intern()方法的描述是:

返回字符串對象的規範化表示形式。

一個初始爲空的字符串池,它由類 String 私有地維護。

當調用 intern 方法時,如果池已經包含一個等於此 String 對象的字符串(用 equals(Object) 方法確定),則返回池中的字符串。否則,將此 String 對象添加到池中,並返回此 String 對象的引用。

它遵循以下規則:對於任意兩個字符串 s 和 t,當且僅當 s.equals(t) 爲 true 時,s.intern() == t.intern() 才爲 true。

所有字面值字符串和字符串賦值常量表達式都使用 intern 方法進行操作。

上面字符串池即爲字符串常量池。明白該題結果的原因了吧。

6)false,false,true

第五題看明白後,第六題就沒什麼好講的了。

來源:http://itmian.com/2011/05/06/%e6%b7%b1%e5%85%a5%e7%90%86%e8%a7%a3javstring/

http://itmian.com/2011/05/05/six-string-interview-question-of-java/

 

 

String.intern(): 

  再補充介紹一點:存在於.class文件中的常量池,在運行期被JVM裝載,並且可以擴充。String的 intern()方法就是擴充常量池的 一個方法;當一個String實例str調用intern()方法時,Java 查找常量池中 是否有相同Unicode的字符串常量,如果有,則返回其的引用,如果沒有,則在常 量池中增加一個Unicode等於str的字符串並返回它的引用;看示例就清楚了 

  示例: 

  String s0= "kvill"; 
  String s1=new String("kvill"); 
  String s2=new String("kvill"); 
  System.out.println( s0==s1 ); 
  System.out.println( "**********" ); 
  s1.intern(); 
  s2=s2.intern(); //把常量池中"kvill"的引用賦給s2 
  System.out.println( s0==s1); 
  System.out.println( s0==s1.intern() ); 
  System.out.println( s0==s2 ); 

 

結果:

 

false

**********

false

true

true

 

 

分析:

Java代碼  收藏代碼
  1. String x = "abc";  
  2. String y = new String("abcd");  

 現在來分析一下內存的分配情況。如圖:


 
可以看出,x與y存在棧中,它們保存了相應對象的引用。第一條語句沒有在堆中分配內存,而是將“abc”保存在常量池中。對於第二條語句,同樣會在常量池中有一個“abcd”的字符串,當new時,會拷貝一份該字符串存放到堆中,於是y指向了堆中的那個“abcd”字符串。不知道polaris有沒有講明白。如果您明白了,那麼做前面那六道題就沒什麼問題了。

發佈了19 篇原創文章 · 獲贊 14 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章