全網最硬核的源碼分析之——String源碼分析

String類在平常開發過程當中使用頻率很是高,可是你們真的認真瞭解過它麼。java

基於jdk1.8

 一:實現接口。程序員

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
  • String類被final關鍵字修飾,不能被繼承,建立後不可修改。
  • java.io.Serializable

  能夠實現序列化,標記接口,用於標識序列化,未實現該接口沒法被序列化。數組

  • Comparable<String>

  能夠比較大小,這個接口只有一個compareTo(T 0)接口,用於對兩個實例化對象比較大小。源碼分析

  • CharSequence

  String本質是個char類型數組,這個接口是一個只讀的字符序列。String、StringBuilder、StringBuffer都實現了這個接口。ui

 二:成員變量this

/** The value is used for character storage. */
private final char value[];

/** Cache the hash code for the string */
private int hash; // Default to 0

  能夠看到,value[]是存儲String的內容的,即當使用String str = "abc";的時候,本質上,"abc"是存儲在一個char類型的數組中的。日誌

 三:實現方法code

再繼續看String類的一些方法實現:對象

*/
    public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }

public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

從上面的三個方法能夠看出,不管是substring、concat仍是replace操做都不是在原有的字符串上進行的,而是從新生成了一個新的字符串對象。說進行這些操做後,最原始的字符串並無被改變。繼承

String對象一旦被建立就是固定不變的,對String對象的任何改變都不影響到原對象,相關的任何操做都會生成新的對象。

4、總結

1.String類初始化後是不可變的(immutable)

String使用private final char value[]來實現字符串的存儲,也就是說String對象建立以後,就不能再修改此對象中存儲的字符串內容,就是由於如此,才說String類型是不可變的(immutable)。程序員不能對已有的不可變對象進行修改。咱們本身也能夠建立不可變對象,只要在接口中不提供修改數據的方法就能夠。
然而,String類對象確實有編輯字符串的功能,好比replace()。這些編輯功能是經過建立一個新的對象來實現的,而不是對原有對象進行修改。好比:

s = s.replace("World", "Universe");

上面對s.replace()的調用將建立一個新的字符串"Hello Universe!",並返回該對象的引用。經過賦值,引用s將指向該新的字符串。若是沒有其餘引用指向原有字符串"Hello World!",原字符串對象將被垃圾回收。

五 推薦閱讀

全網最硬核的源碼分析之——String源碼分析

Spring Boot 自動化配置原理帶圖全面講解

MySQL 3大日誌的做用

全網最硬核的源碼分析之——ArrayList源碼分析

若是感受對您有幫助,但願你們可關注一下,點個贊再走,感謝您的閱讀。
相關文章
相關標籤/搜索