天天看點

JAVA String、StringBuffer、StringBuilder類解讀

JAVA String、StringBuffer、StringBuilder類解讀

字元串廣泛應用 在 Java 程式設計中,在 Java 中字元串屬于對象,Java 提供了 String 類來建立和操作字元串。

Java 可以通過最簡單的​<code>​String str = "this is string"​</code>​,來建立字元串;

也可以通過構造函數建立字元串​<code>​String str2 = new String("this is string")​</code>​來建立字元串。

首先明白一個事,java存在一個常量池,可以用來存儲字元串常量。先知概念:

①【常量池constant pool】管理在編譯時被确定并儲存在已編譯的.class檔案中的一些資料,包括關于類、方法、接口中的常量,和字元串常量。

②【字元串常量池(String pool, String intern pool, String保留池)】 是Java堆記憶體中一個特殊的存儲區域, 當建立一個String對象時,假如此字元串值已經存在于常量池中,則不會建立一個新的對象,而是引用已經存在的對象。

當使用​<code>​new String(“hello”)​</code>​時,JVM會先使用常量池來管理“hello”直接量,再調用String類的構造器來建立一個新的String對象,新建立的對象被儲存在堆記憶體中。即​<code>​new String(“hello”)​</code>​一共産生了兩個字元串對象。

問題:

JVM為了提升性能和減少記憶體開銷,避免字元串的重複建立,維護了一塊特殊的記憶體空間——字元串常量池。

String指派的兩種方式。

1、​<code>​String str = "test";​</code>​

以這種方式指派時,JVM會先從字元串常量池中查詢是否存在"test"這個對象,

如果存在,直接把常量池中"test"的位址傳回給str。如果不存在,則會在常量池中建立"test"對象,并把該對象的位址傳回給str。

是以通過==比較是,str1,str2指向的是同一位址,是以傳回true;

2、​<code>​String str = new String("test");​</code>​

若不存在則會在常量池中建立"test"對象,同時調用String類的構造器在堆中建立"test"這個對象,然後将堆中的這個對象的位址傳回賦給引用str。

若常量池存在則直接調用String類的構造器在堆中建立"test"這個對象,然後将堆中的這個對象的位址傳回賦給引用str。

這時str1和str2分别指向堆中不同的位址,是以傳回false;

答:最流行的Java面試題之一就是:什麼是不可變對象(immutable object),不可變對象有什麼好處,在什麼情況下應該用,或者更具體一些,Java的String類為什麼要設成immutable類型? 不可變對象,顧名思義就是建立後不可以改變的對象,典型的例子就是Java中的String類。

String s = "ABC"; s.toLowerCase();

如上s.toLowerCase()并沒有改變“ABC“的值,而是建立了一個新的String類“abc”,然後将新的執行個體的指向變量s。 相對于可變對象,不可變對象有很多優勢:

1).不可變對象可以提高String Pool的效率和安全性。如果你知道一個對象是不可變的,那麼需要拷貝這個對象的内容時,就不用複制它的本身而隻是複制它的位址,複制位址(通常一個指針的大小)需要很小的記憶體效率也很高。對于同時引用這個“ABC”的其他變量也不會造成影響。

2).不可變對象對于多線程是安全的,因為在多線程同時進行的情況下,一個可變對象的值很可能被其他程序改變,這樣會造成不可預期的結果,而使用不可變對象就可以避免這種情況。 當然也有其他方面原因,但是Java把String設成immutable最大的原因應該是效率和安全。

和 String 類不同的是,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,并且不産生新的未使用對象。

在使用 StringBuffer 類時,每次都會對 StringBuffer 對象本身進行操作,而不是生成新的對象,是以如果需要對字元串進行修改推薦使用 StringBuffer。

StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在于 StringBuilder 的方法不是線程安全的(不能同步通路)。如果一個StringBuffer對象在字元串緩沖區被多個線程使用時,StringBuffer中很多方法可以帶有synchronized關鍵字,是以可以保證線程是安全的,但StringBuilder的方法則沒有該關鍵字,是以不能保證線程安全,有可能會出現一些錯誤的操作。

由于 StringBuilder 相較于 StringBuffer 有速度優勢,是以多數情況下建議使用 StringBuilder 類。

運作速度快慢為:StringBuilder &gt; StringBuffer &gt; String

String:适用于少量的字元串操作的情況

StringBuilder:适用于單線程下在字元緩沖區進行大量操作的情況

StringBuffer:适用多線程下在字元緩沖區進行大量操作的情況

上一篇: Frame Relay