String類的常見面試題,以及String,StringBuffer和StringBuilder的區別

寫幾個String類的常見面試題,覺得可以的老鐵點贊哈,歡迎各路大神指教!內容有點多需要耐心點看完.
先說說String,StringBuffer和StringBuilder的區別吧
    String是字符串常量,用final修飾,StringBuffer是字符串變量,它是線程安全的,StringBuilder也是字符串變量,但是他是線程不安全的.
    String和StringBuffer的區別在於性能,String是不可變的對象,每次對String進行操作實際上是生成了一個新String的對象,而原來的就會成爲垃圾,所以我們在代碼中儘量不對String做大量的操作,但是有一點需要注意的是,JVM對字符串拼接做了一定的優化,比如:String  s = "ab" +"dc";會在編譯的時候直接生成String = "abdc";此時就不存在拼接過程.

StringBuffer和StringBuilder相比較StringBuffer是線程安全的可變字符串,其內部實現是可變的數組,StringBuilder是java5.0新增的一個類,功能和StringBuilder類似,但是線程非安全,因此在沒有多線程問題的前提下,StringBuilder會獲得更好的性能.

    然後說說String的常見面試題:
1.判斷定義爲String類型的s1和s2是否相等
* String s1 = "abc";
* String s2 = "abc";
* System.out.println(s1 == s2); //true
        * System.out.println(s1.equals(s2));    //true

我先直接上一張內存圖然後在解釋一下:

簡單的說創建s1的時候會在常量池中創建一個"abc",這個"abc"有一個地址值,然後s1把引用指向"abc"的地址值;創建s2的時候會在常量池中去檢查是否有"abc",如果有就直接把引用指向"abc"的地址值,所以s1和s2的地址值相等.

2.下面這句話在內存中創建了幾個對象?
* String s1 = new String("abc");
我們先來看一下String類的構造方法:

String(String original)
    初始化一個新創建的 String 對象,使其表示一個與參數相同的字符序列;換句話說,新創建的字符串是該參數字符串的副本。
然後在畫一下內存圖:
綜合構造方法和內存圖簡單的解釋一下:內存的順序是這樣的,先是方法進棧,創建一個s1對象,然後在常量池創建一個"abc",然後在堆內存中複製一個"abc"的副本,但有自己的地址值0x0011,最後再把s1的引用指向0x0011.

3.判斷定義爲String類型的s1和s2是否相等
* String s1 = new String("abc");
* String s2 = "abc";
* System.out.println(s1 == s2); //false
* System.out.println(s1.equals(s2));    //true
這個題和上面的題很像,創建的兩個對象一個引用指向的是堆內存,另一個地址是指向常量池.

 4.判斷定義爲String類型的s1和s2是否相等
* String s1 = "a" + "b" + "c";
* String s2 = "abc";
* System.out.println(s1 == s2); //true
* System.out.println(s1.equals(s2));    //true
這個題是考的jvm的對String類的常量優化機制,String s1 = "a" + "b" + "c";代碼在編譯的時候就會生成String s1 = "abc";在創建s2的時候常量池中已經有"abc"了,會直接把引用指向"abc",所以s1和s2的地址值是一樣的.

5.判斷定義爲String類型的s1和s2是否相等
* String s1 = "ab";
* String s2 = "abc";
* String s3 = s1 + "c";
* System.out.println(s3 == s2);     //false
* System.out.println(s3.equals(s2));    //true
String類的api這樣說的:
Java 語言提供對字符串串聯符號("+")以及將其他對象轉換爲字符串的特殊支持。字符串串聯是通過 StringBuilder(或 StringBuffer)類及其 append 方法實現的。字符串轉換是通過 toString 方法實現的,該方法由 Object 類定義,並可被 Java 中的所有類繼承。
然後我們再來看一張內存圖:

簡單的解釋一下內存中的順序:

①主方法進棧,創建s1對象,然後在常量池中創建"ab",s1把引用指向"ab"的地址值,
②創建s2對象,然後在常量池中創建"abc",s2把引用指向"abc"的地址值,
③創建s3,然後在堆內存中創建StringBuffer或者StringBuilder的對象,利用append()方法,把"abc"賦值給該對象,再利用toString()方法在堆內存中創建出String對象,值爲"abc",地址值爲"0x0022,最後把s3的引用指向0x0022
所以,s2和s3地址值不相等.

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