天天看點

Java核心技術卷I基礎知識3.6.3 不可變字元串

<b>3.6.3 不可變字元串</b>

string類沒有提供用于修改字元串的方法。如果希望将greeting的内容修改為“help!”,不能直接地将greeting的最後兩個位置的字元修改為‘p’和‘!’。這對于c程式員來說,将會感到無從下手。如何修改這個字元串呢?在java中實作這項操作非常容易。首先提取需要的字元,然後再拼接上替換的字元串:

上面這條語句将greeting目前值修改為“help!”。

由于不能修改java字元串中的字元,是以在java文檔中将string類對象稱為不可變字元串,如同數字3永遠是數字3一樣,字元串“hello”永遠包含字元h、e、l、l和o的代碼單元序列,而不能修改其中的任何一個字元。當然,可以修改字元串變量greeting,讓它引用另外一個字元串,這就如同可以将存放3的數值變量改成存放4一樣。

這樣做是否會降低運作效率呢?看起來好像修改一個代碼單元要比建立一個新字元串更加簡潔。答案是:也對,也不對。的确,通過拼接“hel”和“p!”來建立一個新字元串的效率确實不高。但是,不可變字元串卻有一個優點:編譯器可以讓字元串共享。

為了弄清具體的工作方式,可以想象将各種字元串存放在公共的存儲池中。字元串變量指向存儲池中相應的位置。如果複制一個字元串變量,原始字元串與複制的字元串共享相同的字元。

總而言之,java的設計者認為共享帶來的高效率遠遠勝過于提取、拼接字元串所帶來的低效率。檢視一下程式會發現:很少需要修改字元串,而是往往需要對字元串進行比較(有一種例外情況,将來自于檔案或鍵盤的單個字元或較短的字元串彙內建字元串。為此,java提供了一個獨立的類,在3.6.9節中将詳細介紹)。

      c++注釋:在c程式員第一次接觸java字元串的時候,常常會感到迷惑,因為他們總将字元串認為是字元型數組:

這種認識是錯誤的,java字元串大緻類似于char*指針,

當采用另一個字元串替換greeting的時候,java代碼大緻進行下列操作:

的确,現在greeting指向字元串“help!”。即使一名最頑固的c程式員也得承認java文法要比一連串的strncpy調用舒适得多。然而,如果将greeting賦予另外一個值又會怎樣呢?

這樣做會不會産生記憶體遺漏呢?畢竟,原始字元串放置在堆中。十分幸運,java将自動地進行垃圾回收。如果一塊記憶體不再使用了,系統最終會将其回收。

對于一名使用ansi c++定義的string類的c++程式員,會感覺使用java的string類型更為舒适。c++ string對象也自動地進行記憶體的配置設定與回收。記憶體管理是通過構造器、指派操作和析構器顯式執行的。然而,c++字元串是可修改的,也就是說,可以修改字元串中的單個字元。