String&StringBuilder&StringBuffer

String 基礎

String源碼java

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

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

    /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence.  Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
    public String() {
        this.value = "".value;
    }
    ...
    public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }

    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 CharSequence subSequence(int beginIndex, int endIndex) {
        return this.substring(beginIndex, endIndex);
    }

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

分析源碼:
1.String 類爲 final 修飾,說明該類不能被重寫。 2.String類型的字符串實際上是以 字符的形式存儲的,(private final char value[]) 3.任何操做字符串的方法都是創建在新的字符串之上的,字符串的操做不會影響到原來的字符串對象,而是新建一個字符串副本以供操做。安全

String & StringBuilder&StringBuffer

String

String s1 = "daxiong"; String s2 = "daxiong"; String s3 = new String("daxiong"); String s4 = new String("daxiong");多線程

JVM 內存機制中針對不一樣的屬性進行不一樣的分區存儲。字面量以及符號都會存在於方法區的常量池中,這裏以HotSpot虛擬機爲例,那麼 String s1 = "daxiong"; 其中 "daxiong" 字面量就會存儲到方法區的常量池中,當執行到 Stirng s2 = "daixong";的時候虛擬機會到方法區的常量池中進行檢測,若是檢測到常量池中存在"daxiong",那麼就不會再次建立,若是沒有檢測到,則會從新建立,這裏很顯然已經存在,則不會再次建立新的"daxiong"。而對於String s3 = new String("daxiong");JVM專門分配一塊內存區域叫作堆來存儲對象實例,也就是經過new關鍵字建立的對象(注意:隨着技術的發展,當前的虛擬機不是全部的經過new關鍵字建立的實例都會放到堆中),那麼s3這個實例對象就會在堆上被分配內存空間,固然String s4 = new String("daixong");也一樣會在堆上被分配內存空間。而這二者的引用都會存儲到棧空間,棧空間又分爲JVM虛擬機棧和本地方法棧兩類,上面的實例的引用都在JVM虛擬機棧中存儲。因此綜上所述:s1 == s2,s1 != s3/s4,s3 != s4;app

StringBuilder

String s = "hello";
for(int i = 0;i < 1000;i++){
    s += "world";
}

上面這段代碼是經過String直接操做的,那麼根據以前分析的String的特性可知:每執行一步 "+" 操做,須要先建立一個新的對象,而後將原對象賦值給新對象,而後在新對象上進行 "+"操做,而後再將新對象返回。以此類推...,執行完上面的代碼須要建立 1000 個新對象,很浪費空間。ui

StringBuilder sb = new StringBuilder("hello");
for(int i = 0;i < 1000;i++){
    sb.append("world");
}

上面這段代碼只會建立一個對象,即StingBuilder,它的操做字符串效果是在原對象上進行的,不會浪費太多空間。this

StringBuffer

經過查看源碼發現StringBuilder 和 StringBuffer的成員變量和方法大體相同,只不過StringBuffer 在方法上加入了同步關鍵字:synchronized,也就是說StringBuffer提供了多線程訪問線程安全策略,是線程安全的。那麼從這裏可知:線程

StringBuilder 執行效率快,線程不安全;StringBuffer執行慢,線程安全。code

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息