Java String類面試題

字符串對象是一種特殊的對象.String類是一個不可變的類..也就說,String對象一旦創建就不允許修改

String類有一個對應的String池,也就是 String pool.每一個內容相同的字符串對象都對應於一個pool裏的對象.

1. 看下面一段代碼.

  String s = new String("abc");
  String s1 = "abc";
  String s2 = new String("abc");


  System.out.println(s == s1);
  System.out.println(s == s2);
  System.out.println(s1 == s2);

請問 前面三條語句分別創建了幾個對象,分別是什麼.後面的輸出分別是什麼

(1)String s = new String("abc"); 這句,創建了兩個對象..其內容都是"abc".注意,s不是對象,只是引用.只有new生成的纔是對象.

創建的流程是,首先括號裏的"abc"先到String pool裏看有沒"abc"這個對象,沒有則在pool裏創建這個對象..所以這裏就在pool創建了一個"abc"對象.然後 通過new語句又創建了一個"abc"對象..而這個對象是放在內存的堆裏. .這裏的s指向堆裏的對象.

(2) String s1 = "abc"; 這條語句,s1當然還是引用.沒啥可說的.後面的"abc".其實就是上面括號裏的"abc".執行的是相同的操作.即 在pool裏查找有沒"abc"這個對象.沒有則創建一個...很顯然,第一條語句在pool裏已經創建了一個"abc".所以這條語句沒有創建對象,s1指向的是pool中的"abc"

(3)String s2 = new String("abc"); 這條語句,其實和第一條是一樣的,但是,因爲第一條已經在pool中創建了"abc"這個對象,所以,這條語句創建了一個對象.s2指向的是堆裏的"abc".注意,雖然內容都是"abc",s與s2表示的是不同的對象

(4)接下來就很好說了.下面的三個==判斷.(注意,==永遠是判斷內存地址是否相等) s與s1,一個指向堆裏的對象,一個指向pool裏的.很明顯是不同的對象.s與s2.上面說了,雖然都是指向堆裏的對象,內容也是"abc",但是也不是相同的對象.s1與s2.一個指向pool,一個指向堆.也不是相同的對象.所以三個都返回false.

2. 第二個問題

  String s = new String("abc");
  String s1 = "abc";
  String s2 = new String("abc");
  
  System.out.println(s == s1.intern());
  System.out.println(s == s2.intern());
  System.out.println(s1 == s2.intern());

求最後輸出是什麼

解答.最後的答案是 false false true

intern()方法.按照jdk的幫助文檔來說,是返回字符串對象的規範化表示形式。通俗一點說,就是返回對應這個字符串內容的那個pool裏的對象.這樣說也許還看不太明白,那可以拿具體例子來說

s1.intern().他的執行流程是,在pool裏去查找s1對應的內容(也就是"abc").如果找到,則返回pool裏的對象.如果沒有(老實說,我沒想到有哪種情況是沒有的),則在Pool創建這個對象,並返回...

這樣就很容易理解了.s1.intern返回的是pool裏的"abc"對象.與s這個堆裏的對象肯定不同,返回false.同理,s與s2.intern()也肯定不同,返回false.第三個,s1與s2.intern().其中s2.intern()返回的是pool中的"abc"對象,而s1也是指向pool中的"abc"對象.所以返回的是true:

3. 第三個問題

  String hello = "hello";
  String hel = "hel";
  String lo = "lo";
  
  System.out.println(hello == "hel" + "lo");
  System.out.println(hello == "hel" + lo);

求輸出的結果

解答 true false

首先,上面已經說明了,hello hel lo這三個都是指向pool中的對象..

現在我們考慮"hel" + "lo" 按照內容來說,兩個相加也就是"hello".這個時候,這個會返回pool中的"hello"對象.所以,hello == "hel" + "lo" 返回的是true .

而"hel" + lo 雖然內容也是"hello",但是它將在堆裏面生成一個"hello"對象,並返回這個對象...所以這裏的結果是false

總結一下就是,如果加號兩邊的是字面值(字面值就是直接在""裏寫的值,比如上面的"hel"與"lo"),那麼將在pool裏查找有沒對應內容的對象(這裏的內容就是"hello"),並返回pool裏的對象.這和hello是一樣的....

如果加號兩邊不滿足上面的條件(比如,兩邊的值是引用值或者堆裏的字符串對象).那麼將不會再pool裏查找"hello",而是直接在堆裏生成一個新的對象...

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