深入理解java String

JDK 中的String 類是一個簡單而又不平凡的類, 它是java 語言的核心類。我們今天就來講講java String這個類的故事。


先看java String 類源碼:


深入理解java String


從源碼中我們可以看到String 類是被定義為final 的,這就意味著String 類是不可以被繼承的,裡面的方法也被定義為final 的,因為String 類是java 語言的核心類,所以java語言設計者基於安全和效率考慮,不予許String 類可以被繼承。(我們先在這裡留下一個問題:為什麼String 類被定義為final, String 類的方法也被定義為fianl?)


一.字符串的創建形式

String 的創建形式有以下三種基本形式:

1. String str = "string"

2. String str2 = new String("string");

3. String str3 = “string".intern()

這三種形式創建字符串返回的結果是一樣的,但是java 虛擬機在內存分配上是不同的。

在解釋這點之前,我們先來看看java 虛擬機對內存分配:

java棧內存(私有數據區): 主要用來存儲局部變量,(基本數據類型變量,對象引用變量)

java堆內存(共享數據區):主要存放實例對象

方法區(共享數據區):主要存放加載的類信息,靜態變量,常量

常量池(共享數據區):常量池是方法區的一部分,用來存儲字面常量、使用final修飾的變量以及符號引用

第一種方法在創建字符串str 時,java虛擬機會在方法區的常量池中判斷是否存在具有和字符串string內容相同的String對象:如果常量池不存在和賦值字符串內容相同的對象,虛擬機就在常量池中分配內存並創建該String對象,並將String對象的引用賦值給String類型的變量;如果常量池存在與賦值字符串內容相同的對象,虛擬機會直接將該對象的引用賦值給String類型的變量。這種創建方式對連續創建同一字符串內容的String對象特別有用,內存利用效率非常高效

第二種方法, intern()是一個Native方法,底層調用C++的 StringTable::intern 方法,虛擬機會創建兩個String對象:一個String對象是在常量池中創建,如果常量池中已有字符串內容相同的對象,則不創建;一個String對象是在運行數據區的堆中創建,將在常量池中創建的String對象的字符數組複製到在堆中創建的String對象。

第三種方法,java虛擬機會返回常量池種對象的引用給變量str3。

所以我們在創建一個字符串的時候,基於內存效率的考慮,多用方法一。


所以, String被設計成不可變和不能被繼承的原因,可以理解為考慮效率和安全,只有當字符串不可變,String 常量池才可以實現,從而在運行時節省很多heap 空間。


二, String 類中常用方法

方法

用途

boolean startsWith(String str)

boolean endsWith(String str)

boolean contains(CharSequence str)

檢查開始或者結束字符

int indexOf(String str)

int lastIndexOf(String str)

int indexOf(String str, int fromIndex)

int lastIndexOf(String str, int fromIndex)

字符索引,如果沒有匹配則返回-1

String replace(CharSequence oldStr, CharSequence newStr)

字符替換

String toUpperCase()

String toLowerCase()

返回大小寫字符

String trim()

去除首尾空格


三, 字符串連接

java 語言使用操作符+ 來拼接字符串, 如果要將字符串拆開,可以用substring 方法,結合indexOf 方法對字符串進行拼接。


深入理解java String


輸出結果:

ebcf4464091342229224034deb0fcf2e

ebcf446409


四。 更高效的字符串處理類StringBuilder 與StringBuffer

當對字符串進行修改的時候,需要使用 StringBuffer 和 StringBuilder 類。

和 String 類不同的是,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,並且不產生新的未使用對象。StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在於 StringBuilder 的方法不是線程安全的(不能同步訪問)。

由於 StringBuilder 相較於 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程序要求線程安全的情況下,則必須使用 StringBuffer 類


深入理解java String


五, String 的equals 與==

下面是String 類的equals 方法, equals 是Object 類中的方法。


深入理解java String


從源碼上看

1. 若當前對象和比較的對象是同一個對象,即return true。也就是Object中的equals方法。

2.若當前傳入的對象是String類型,則比較兩個字符串的長度,即value.length的長度。

若長度不相同,則return false

若長度相同,則按照數組value中的每一位進行比較,不同,則返回false。若每一位都相同,則返回true。

若當前傳入的對象不是String類型,則直接返回false


分享到:


相關文章: