Python知識分享網(wǎng) - 專業(yè)的Python學(xué)習(xí)網(wǎng)站 學(xué)Python,上Python222
《劍指offer》Java-String、StringBuffer 和 StringBuilder 的區(qū)別 PDF 下載
匿名網(wǎng)友發(fā)布于:2024-01-16 10:00:40
(侵權(quán)舉報(bào))
(假如點(diǎn)擊沒反應(yīng),多刷新兩次就OK!)

《劍指offer》Java-String、StringBuffer 和 StringBuilder 的區(qū)別 PDF 下載  圖1

 

 

 

 

資料內(nèi)容:

 

簡單認(rèn)識這三個(gè)對象
String
String 表示的就是 Java 中的字符串,我們?nèi)粘i_發(fā)用到的使用 "" 雙引號包圍的數(shù)都是字符串的實(shí)
例。String 類其實(shí)是通過 char 數(shù)組來保存字符串的。下面是一個(gè)典型的字符串的聲明
String s = "abc";
上面你創(chuàng)建了一個(gè)名為 abc 的字符串。
字符串是恒定的,一旦創(chuàng)建出來就不會被修改,怎么理解這句話?我們可以看下 String 源碼的聲明
告訴我你看到了什么?String 對象是由 final 修飾的,一旦使用 final 修飾的類不能被繼承、方法不能
被重寫、屬性不能被修改。而且 String 不只只有類是 final 的,它其中的方法也是由 final 修飾的,換句
話說,Sring 類就是一個(gè)典型的 Immutable 類。也由于 String ?的不可變性,類似字符串拼接、字符串
截取等操作都會產(chǎn)生新的 String 對象。
所以請你告訴我下面
String s1 = "aaa";
String s2 = "bbb" + "ccc";
String s3 = s1 + "bbb";
String s4 = new String("aaa");
分別創(chuàng)建了幾個(gè)對象?
首先第一個(gè)問題,s1 創(chuàng)建了幾個(gè)對象。字符串在創(chuàng)建對象時(shí),會在常量池中看有沒有 aaa 這個(gè)字
符串;如果沒有此時(shí)還會在常量池中創(chuàng)建一個(gè);如果有則不創(chuàng)建。我們默認(rèn)是沒有的情況,所以會
創(chuàng)建一個(gè)對象。下同。
那么 s2 創(chuàng)建了幾個(gè)對象呢?是兩個(gè)對象還是一個(gè)對象?我們可以使用 javap -c 看一下反匯編代

public class com.sendmessage.api.StringDemo {
public com.sendmessage.api.StringDemo();
Code:
0: aload_0
1: invokespecial #1 // 執(zhí)行對象的初始化方法
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // 將 String aaa 執(zhí)行入棧操作
2: astore_1
3: ldc #3 // String bbbccc
5: astore_2
6: return
}
編譯器做了優(yōu)化 String s2 = "bbb" + "ccc" 會直接被優(yōu)化為 bbbccc 。也就是直接創(chuàng)建了一個(gè) bbbccc
對象。
javap 是 jdk 自帶的 反匯編 工具。它的作用就是根據(jù) class 字節(jié)碼文件,反匯編出當(dāng)前類對應(yīng)的
code 區(qū)(匯編指令)、本地變量表、異常表和代碼行偏移量映射表、常量池等等信息。
javap -c 就是對代碼進(jìn)行反匯編操作。
下面來看 s3,s3 創(chuàng)建了幾個(gè)對象呢?是一個(gè)還是兩個(gè)?還是有其他選項(xiàng)?我們使用 javap -c 來看
一下
我們可以看到,s3 執(zhí)行 + 操作會創(chuàng)建一個(gè) StringBuilder 對象然后執(zhí)行初始化。執(zhí)行 + 號相當(dāng)于是執(zhí)
行 new StringBuilder.append() 操作。所以
String s3 = s1 + "bbb";
==
String s3 = new StringBuilder().append(s1).append("bbb").toString();
// Stringbuilder.toString() 方法也會創(chuàng)建一個(gè) String
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
所以 s3 執(zhí)行完成后,相當(dāng)于創(chuàng)建了 3 個(gè)對象。
下面來看 s4 創(chuàng)建了幾個(gè)對象,在創(chuàng)建這個(gè)對象時(shí)因?yàn)槭褂昧?new 關(guān)鍵字,所以肯定會在堆中創(chuàng)建
一個(gè)對象。然后會在常量池中看有沒有 aaa 這個(gè)字符串;如果沒有此時(shí)還會在常量池中創(chuàng)建一個(gè);
如果有則不創(chuàng)建。所以可能是創(chuàng)建一個(gè)或者兩個(gè)對象,但是一定存在兩個(gè)對象。
說完了 String 對象,我們再來說一下 StringBuilder 和 StringBuffer 對象