String StringBuffer StringBuilder比較

image.png

String 是不可變量。用final關(guān)鍵字修飾字符數(shù)組來保存字符串。

image.png

StringBuffer 和 StringBuilder都繼承自AbstractStringBuilder 類,在 AbstractStringBuilder 中也是使用字符數(shù)組保存字符串char[]value 但是沒有用 final 關(guān)鍵字修飾,所以這兩種對象都是可變的。

image.png

線程安全性

String中的對象是不可變的,即常量,所以線程安全。

StringBuffer對方法或者繼承的方法加了同步鎖(synchronized),所以線程安全。

StringBuilder沒有添加同步鎖,所以不是線程安全。

性能

每次對String類型進(jìn)行改變時,都會生成一個新的String對象,然后將指針指向新的String對象。

StringBuffer 每次都會對 StringBuffer 對象本身進(jìn)行操作,而不是生成新的對象并改變對象引用。相同情況下使用 StringBuilder 相比使用 StringBuffer 僅能獲得 10%~15% 左右的性能提升,但卻要冒多線程不安全的風(fēng)險。

最佳實踐

操作少量的數(shù)據(jù): 適用String
單線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù): 適用StringBuilder
多線程操作字符串緩沖區(qū)下操作大量數(shù)據(jù): 適用StringBuffer

字符串常量實例

    public static void main(String[] args) {

        // 字符串常量,分配在常量池中,編譯器會對其進(jìn)行優(yōu)化,  Interned table
        // 即當(dāng)一個字符串已經(jīng)存在時,不再重復(fù)創(chuàng)建一個相同的對象,而是直接將s2也指向"hello".
        String s1 = "hello";
        String s2 = "hello";

        // new出來的對象,分配在heap中.s3與s4雖然它們指向的字符串內(nèi)容是相同的,但是是兩個不同的對象.
        // 因此==進(jìn)行比較時,其所存的引用是不同的,故不會相等
        //這句話創(chuàng)建了兩個對象,一個"hello"在編譯時創(chuàng)建在常量池中,一個在運行時創(chuàng)建在堆中
        String s3 = new String("hello");
        String s4 = new String("hello");

        System.out.println(s1 == s2);   // true
        System.out.println(s3 == s4);   // false
        System.out.println(s3.equals(s4));   // true
        System.out.println(s1 == s3);   //false
        System.out.println(s3.equals(s1)); //true
        // String中equals方法已經(jīng)被重寫過,比較的是內(nèi)容是否相等.
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容