你在面試時,面試官讓你講講String String Buffer String Builder的區(qū)別,你是否能流暢的、完整的敘述出他們?nèi)叩膮^(qū)別?
?先說結(jié)論
- 相同點(diǎn): 他們的底層都是由char數(shù)組實現(xiàn)的。
- 不同點(diǎn):
- String對象一旦創(chuàng)建,是不能修改的,如果要修改,會重新開辟空間來存儲修改后的對象;而String Buffer和String Builder創(chuàng)建的對象是可以修改的。
- String Buffer是線程安全的,他幾乎所有方法都被synchronization 所修飾,允許采用多線程的方式執(zhí)行添加或刪除字符的操作,但是效率比較低;而String Builder是單線程的。如果所有字符串在一個單線程中編輯(通常都是這樣),則應(yīng)該使用String Builder。這兩個類的API大部分是相同的。
總結(jié)
- 當(dāng)在程序中需要頻繁的更改字符串的內(nèi)容時,不要使用String(會浪費(fèi)大量的空間)
- 如果是要考慮線程下的安全問題時,使用StringBuffer
- 否則使用String Builder
?String類
String的三種構(gòu)造方法
public static void main(String[] args) {
// 使用常量串構(gòu)造
String s1 = "hello bit";
System.out.println(s1);
// 直接newString對象
String s2 = new String("hello bit");
System.out.println(s1);
// 使用字符數(shù)組進(jìn)行構(gòu)造
char[] array = {'h','e','l','l','o','b','i','t'};
String s3 = new String(array);
System.out.println(s1);
}
我們要理解String類,首先要搞清楚String的底層
通過源碼可以看出
String是一個引用類型
我們舉幾個實際的例子
來更清楚的了解String的本質(zhì)
請你先判斷這個表達(dá)式的結(jié)果是什么
答案為true
我們畫圖來理解
再判斷一下這個表達(dá)式的值是什么
結(jié)果為false
?字符串的不可變性
- String類被final修飾,表明該類不能被繼承
- value被修飾被final修飾,表明value自身的值不能改變,即不能引用其它字符數(shù)組,但是其引用空間中的內(nèi)容可以修改。
?為什么String要設(shè)置成不可變類型
- 方便實現(xiàn)字符串對象池. 如果 String 可變, 那么對象池就需要考慮寫時拷貝的問題了.
- 不可變對象是線程安全的.
- 不可變對象更方便緩存 hash code, 作為 key 時可以更高效的保存到 HashMap 中
易錯點(diǎn)
- Java中有常量優(yōu)化機(jī)制,“Hello"和"World"本身就是字符串常量,所以在編譯時,會直接把"Hello"和"World"合并成"HelloWorld"字符串,又因為在執(zhí)行s3的時候已經(jīng)在常量池中創(chuàng)建了"HelloWorld".
- 當(dāng)變量與字面量或變量與變量進(jìn)行拼接時,會在堆中創(chuàng)建一個StringBuilde對象,然后使用StringBuilder的append()方法將變量與字面量或變量與變量進(jìn)行拼接,最后調(diào)用toString()方法轉(zhuǎn)成String對象。所以s5、s6、s7指向的都是堆內(nèi)存中String對象的地址值。
public static void main(String[] args) {
final String s1="Hello";
String s2="HelloWorld";
String s3=s1+"World";
System.out.println(s2==s3); //true
}
被final修飾表示是一個常量,所以此時s1+“World"就相當(dāng)于"Hello”+“World”,結(jié)果仍然是一個常量。
有人說:字符串不可變是因為其內(nèi)部保存字符的數(shù)組被final修飾了,因此不能改變。
這種說法是錯誤的,不是因為String類自身,或者其內(nèi)部value被final修飾而不能被修改。
final修飾類表明該類不想被繼承,final修飾引用類型表明該引用變量不能引用其他對象,但是其引用對象中的內(nèi)容是可以修改的。
所有涉及到可能修改字符串內(nèi)容的操作都是創(chuàng)建一個新對象,改變的是新對象文章來源:http://www.zghlxwxcb.cn/news/detail-855481.html
以上就是本文所有內(nèi)容,如果對你有幫助的話,點(diǎn)贊收藏支持一下吧!??????文章來源地址http://www.zghlxwxcb.cn/news/detail-855481.html
到了這里,關(guān)于【Java掃盲篇】String、String Buffer和String Builder的區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!