首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 不變字串機制:String 不可變性設計與 StringBuffer 效能優化

     編輯:Java 相關知識

觀察下列代碼:

//: Stringer.java
public class Stringer {
    static String upcase(String s) {
        return s.toUpperCase();
    }
    public static void main(String[] args) {
        String q = new String("howdy");
        System.out.println(q); // howdy
        String qq = upcase(q);
        System.out.println(qq); // HOWDY
        System.out.println(q); // howdy (原物件未變)
    }
} ///:~

q 傳入 upcase() 時實為參考副本,指向同一物理位置。方法內區域參考 s 隨方法結束消失,回傳的是新物件參考,原 q 完全不受影響。

1. 隱式常數與 C++ const 對比

呼叫 upcase(s) 時,我們通常不希望參數被修改——參數是提供資訊給閱讀者,非供修改。這項保證讓代碼更易讀寫。

C++ 需 const 關鍵字協助程式設計師承諾不修改原物件,但需處處記得加 const,易混淆難記憶。Java 透過 不可變物件設計 從語言層面解決此問題。

2. 運算子 + 覆寫與 StringBuffer

String 物件被設計為不可變。查閱文件可見:所有修改 String 的方法實際建立並回傳新 String,原物件原封未動。Java 無 const,但可自行實作不可變模式。

不可變物件完美解決別名問題:多重別名指向同一唯讀物件絕無副作用。

但對某些操作(如字串連接 +),產生新物件效率極低:

String s = "abc" + foo + "def" + Integer.toString(47);

若每次 + 都產生新 String,會產生大量中間物件頻繁觸發 GC。

解決方案:可變夥伴類 StringBuffer

編譯器自動建立 StringBuffer 計算上述運算式:

//: ImmutableStrings.java
public class ImmutableStrings {
    public static void main(String[] args) {
        String foo = "foo";
        String s = "abc" + foo + "def" + Integer.toString(47);
        System.out.println(s);
        // 等價的 StringBuffer 手寫版:
        StringBuffer sb = new StringBuffer("abc");
        sb.append(foo);
        sb.append("def");
        sb.append(Integer.toString(47));
        System.out.println(sb);
    }
} ///:~

編譯器內部做法等同手寫 StringBuffer 版本——建立一個緩衝區,append() 直接加入字元,避免大量中間物件。雖仍會為字面常數建立 String 物件,但效率大幅提升。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved