1. 程式人生 > >String底層原理

String底層原理

今天模擬面試遇到一位同學,剛好問到一個問題

我問他 String的底層原理是什麼

他思考了一會說不知道。

那麼我們在面試的時候有可能會遇到類似的問題,怎麼去解答,肯定是要去看String的原始碼的

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    

    private final char value[];

     private int hash; // Default to 0

    
    private static final long serialVersionUID = -6849794470754667710L;
    
    ......此處省略N多程式碼
    
    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

}

在上面 貼出了String的原始碼,我們可以看到,String類是final修飾的,然後還有個成員屬性 value  它也是final的並且是一個char型別的陣列

通過構造方法可以看到,我們傳遞的引數值 是直接賦值給了 value 

那麼我們說明 String它是一個不可變字串,底層是一個char型別的陣列

實際上我們經常 這樣寫 String  a = "abc"; 這個時候 宣告的變數值是在常量池中的。

到此,有的同學可能要說了,String裡面我們不是可以使用 + 連線符 來進行String的拼接嗎。

的確如此,我們是可以使用 "+" 來拼接字串,不過 這裡 jdk的虛擬機器是做了優化的,並不是表面看到的使用 連線符 對原來的String做了拼接,那麼我們來看下 它是如何編譯的。

有如下程式碼:

public class Test{
	public static void main(String [] args){
			String str = "abc";
			String str1= "def";
			str = str+str1;
			System.out.println(str);
	}
}

我們在控制檯 中 通過 javac 編譯,然後通過java執行 看到結果是

結果都知道是 "abcdef" 那麼這個地方的str到底是否被改變,我們可以看編譯後的class位元組碼檔案

我們通過 javap -c Test 來觀察,結果如下圖

我們看到Code 的 第 0 和 第 3 標識處,是我們宣告的變數值  "abc" 和 "def"

再往下走,我們在java中的程式碼是使用了 "+" 連線符號的,此處看到 Code 第  6 處 new StringBuilder  

再往下走,看到 Code 的第 14 和 第 18 ,使用了StringBuilder的 append(),那麼我們可以得出一個結論,我們在使用String的時候,使用連線符,並不是表面看到的是直接操作原來的變數做值的拼接,而是使用的StringBuilder物件,追加的內容,

最後 在 Code的21處,有一個 toString()方法,是把當前StringBuilder的物件變成了String。

好了,到此,我們剖析String原始碼到此結束。

結論就是 String底層是一個不可變字串,使用連線符的時候,實際上是經過了StringBuilder的優化處理的。並不是在原來的String物件中做追加