1. 程式人生 > >java中的字串型別(String、StringBuffer、StringBuilder)

java中的字串型別(String、StringBuffer、StringBuilder)

一、首先來說一下JVM相關的一些知識

我們先來了解一下JVM記憶體中的棧(stack)、堆(heap)和方法區:

  •  棧中儲存的是:基本資料型別的變數、物件的引用、函式呼叫的現場。

  •  堆中儲存的是:通過new關鍵字和構造器建立的物件。堆是垃圾收集器管理的主要區域。

  •  它們之間的區別是:棧中的資料可以共享、棧空間操作起來最快但是棧很小,通常大量的物件都是放在堆空間,棧和堆的大小都可以通過JVM的啟動引數來進行調整,棧空間用光了會引發StackOverflowError,而堆和常量池空間不足則會引發OutOfMemoryError。

  •  舉例說明:String str = new String(“hello”)這個語句中變數str放在棧上,用new創建出來的字串物件放在堆上,而”hello”這個字面量是放在方法區的。

String型別的值是存在於常量池中的

private final char value[];

從String類的原始碼可以看出String是用字串陣列來儲存物件的,並且是final型別的,這就說明String型別的物件被聲明後是不能改變的,每次改變String型別的物件後就會產生一個新的物件,然後將指標指向新的物件。(兩種建立方式還有區別)所以當一個物件需要頻繁的改變的時候不應該被宣告稱String型別的,因為此時會產生大量新的物件,導致JVM的GC,影響程式效能。

二、String

看兩個例子

String s1=“java”;

String s2=new String(“java”);

這兩種方式創建出的物件雖然都是不可變的,但是建立方式時不同的。

第一種直接賦值的建立方式JVM首先會檢查字串常量池中有沒有”java”這個字串物件存在,如果有就返回java物件的引用,否則就在字串常量池中新建一個字串物件,並將它的引用返回。當改變這個字串的時候回重新檢查字串常量池中是否有新的字串。

第二種建立方式不管字串常量池中有沒有相同內容的物件,JVM都會在堆中建立一個新的物件,並將物件的引用返回。過程是,當使用new建立String物件時首先從字串常量池中取一個例項的引用,然後在堆中新建一個物件,如果常量池中沒有相同內容的例項則只在堆中建立一個物件,當呼叫intern方法後才將對應的字串序列化放入常量池中。

  • String物件的例項呼叫intern方法後,可以讓JVM檢查常量池,如果沒有例項的value屬性對應的字串序列比如"123"(注意是檢查字串序列而不是檢查例項本身),就將本例項放入常量池,如果有當前例項的value屬性對應的字串序列"123"在常量池中存在,則返回常量池中"123"對應的例項的引用而不是當前例項的引用,即使當前例項的value也是"123"。

三、StringBuffer和StringBuilder

StringBuffer執行緒安全

StringBuilder執行緒不安全,速度優於StringBuffer,通常用於單執行緒

(待續)