java --String類解決面試問題

一、概述

字符串對象是一種特殊的對象.String類是一個不可變的類..也就說,String對象一旦建立就不容許修改 String類有一個對應的String池,也就是 String pool.每個內容相同的字符串對象都對應於一個pool裏的對象面試

public class Demo {
    public static void main(String[] args) {
        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);
    }
}

第一個問題

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

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

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

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

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

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

第二個問題

public class Demo {
    public static void main(String[] args) {
        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:

第三個問題

public class Demo {
    public static void main(String[] args) {
        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());
    }
}

求輸出的結果

解答 true false

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

如今咱們考慮"hel" + "lo" 按照內容來講,兩個相加也就是"hello".這個時候,這個會返回pool中的"hello"對象.因此,hello == "hel" + "lo" 返回的是true .

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

二、 Java技術——你真的瞭解String類的intern()方法嗎

轉載地址:Java技術——你真的瞭解String類的intern()方法嗎

三、經過六個題目完全掌握String筆試面試題

demo1

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

demo2

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

demo3

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

demo4

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";  
    }

demo5

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);  
}

demo6

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 第五題看明白後,第六題就沒什麼好講的了

四、轉載地址

轉載地址:jdk在線文檔 String.intern()方法

轉載地址:經過六個題目完全掌握String筆試面試題

轉載地址:Java技術——你真的瞭解String類的intern()方法嗎

轉載地址:JAVA --String類筆試面試題

相關文章
相關標籤/搜索