在Java學習中,String、StringBuffer、StringBuilder三者是很重要的,在編寫代碼中常常使用到他們,那麼深刻的瞭解他們的異同是很是重要的,接下里咱們詳細剖析下這三個的異同之處java
首先總結下這三者的區別:編程
1.基本區別安全
String的對象不可變,StringBuffer和StringBuilder的對象是可變的多線程
2.性能區別app
三者中StringBuilder執行速度最佳,StringBuffer次之,String的執行速度最慢(String爲字符串常量,而StringBuilder和StringBuffer均爲字符串變量,String對象一旦建立後該對象是不可更改的,後二者的對象是變量是能夠更改的)函數
3.安全區別性能
String、StringBuffer是線程安全的,StringBuilder是線程不安全的(因此若是程序是單線程的使用StringBuilder效率高,若是是多線程使用StringBuffer或者String)學習
其次總結下這三者的相同:ui
1.三者在java中都是用來處理字符串的spa
2.三個類都被final修飾,所以都是不可繼承的
3.StringBuilder與StringBuffer有公共父類AbstractStringBuilder(抽象類)
接下來咱們從源碼和案例深刻分析這三者:
1.String
String經常使用方法:
1.length() 獲取字符串長度
2.replace() 替換字符串中某些字符
3.equals() 比較兩個字符對象內容是否相同
4.substring() 截取一個新的字符串,它是此字符串中的子串
5.trim() 將字符串開頭的空白(空格)和尾部的空白去掉
6.indexOf() 求某個字符在字符串中的位置
7.charAt() 求一個字符串中某個位置的值
8.toLowerCase() 將字符串中全部的大寫改變成小寫
9.toUpperCase() 將字符串中全部的小寫改變爲大寫
注意:
1.String是final類型,不可被繼承;
2.String的對象不可變
從上面這個案例咱們發現a對象的內容被改變了,不是說不能改變麼,這裏咱們不能被表面迷惑,咱們再看下面的程序
咱們發現字符串a被從新賦值後其實已經不是它本身了,從hashCode值能夠看出。當a字符串建立賦值maxbill,而後從新賦值時又會建立一個a對象值爲:maxbill1993,此時844527467是一已經在等待GC回收了,咱們看到的其實是-1438782163對象。因此咱們在程序中對字符串使用+鏈接時,並非把內容動態的改變進去,而是每次都會建立一個新的String對象去放新的字符內容,原來的對象會等着GC回收,因此這也是String爲啥相比其餘二者執行慢的緣由了。
2. StringBuffer
從StringBuffer類的源碼能夠看出,其方法都被同步鎖synchronized修飾,所以是線程安全的,所以在多線程編程中操做字符串是推薦使用爲何說StringBuffer比String的執行速度要高,前面說了String的原理,是致使其慢的緣由,StringBuffer相比快是由於使用了字符串變量,是能夠動態改變的,沒必要像String同樣老是去建立對象賦值新內容,咱們
看下面的案例就明白了
由上面的案例能夠看出StringBuffer在修改字符串內容時,不會建立新的對象,所以它比String類效率更高
StringBuffer經常使用方法:
1.length() 獲取StringBuffer字符長度
2.append() 向StringBuffer增長字符
3.delete() 刪除StringBuffer中的字符
4.replace() 替換StringBuffer中的字符
5.insert() 向StringBuffer中插入字符
6.toString () 把StringBuffer轉成字符串
StringBuffer的append方法源碼解讀:
調用了父類的append方法,咱們看下父類append的源碼
基本原理:使用append()方法在字符串後面追加東西的時候,若是長度超過了該字符串存儲空間大小了就須要進行擴容,構建新的存儲空間更大的字符串,將舊的數據的複製過去
詳細原理:char value[]用來存儲數據,int count用來記錄字符長度,StringBuffer初始16個字符容量 ,先記錄下傳進來字符串的長度,而後使用ensureCapacityInternal函數判是否須要擴容,若是容量不夠則使用newCapacity進行擴容,新容量擴爲原來2倍+2,存儲容量夠了使用getChars函數複製數據,最後將count更新。
3. StringBuilder
StringBuilder和StringBuffer的使用方法和原理基本一致的,惟一的區別就是StringBuilder是線程不安全的,執行效率要比StringBuffer高,所以當時單線程的時候推薦使用線程不安全的StringBuilder效率更高一些,若是是多線程推薦使用StringBuffer來保證線程安全