String類,StringBuffer類轉字符數組


String不可變類型和StringBuffer可變類型

String類和StringBuffer類都是字符串表示類,區別在於String對象引用變量是不可變的,而StringBuffer類對象引用變量是可變的。

我當時學的時候也會很不理解這個可變不可變的區別,后面看了一篇博客才懂了這個意思(https://www.cnblogs.com/yumiaoxia/p/9010721.html#commentform)。

方法傳參,基本數據類型傳的是常量值,而引用數據類型傳的是地址值。但是String對象也是引用類型,傳參方法原值同樣沒有發生改變

public class Test {
    public static void main(String[] args) {
        String str = "java";
        StringBuffer sbf = new StringBuffer("java");
        fun(str,sbf);
        System.out.println("String類型str:"+str+"\nStringBuffer類型sbf:"+sbf);
    }
    public static void fun(String str,StringBuffer sbf){
        str = str + "world";
        sbf.append("world");
    }
}

這雖然也能解釋String是不可變的,StringBuffer是可變的,但還是很牽強。

后面查了下資料,意思是說String類是不可改變類(圖來自上面提到的博客),也就是說String類也有那么一個屬性由fina修飾,在構造方法初始化,存儲字符串的值。

 之后我也去看了一眼String的源碼,果然就是這樣

//String部分源碼
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    private final char value[];
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }
}

可以看到它確實是有個final,private修飾char數組類型屬性,其實我看到這又迷惑了,數組是引用類型,而final修飾引用類型只是鎖定它的地址值不會被改變,它本身存的值還是可以改變的,但是下面這個有參構造解開了我的疑惑,String對象初始化賦值時,會將自己的value屬性指向輸入字符串的value屬性,而這個value屬性是沒有setter方法,所以一旦初始化,則里面的值是不會改變的。String還有一個有參構造,參數是傳入一個字符數組,如果在方法中是將value屬性指向這個字符數組,那只要改變傳入的字符數組值該String對象值也會跟着改變,豈不是違反了前面所說的String不可變。之后我找到這個方法。

可以看到它並沒有將value屬性直接指向傳入的value字符數組,而是創建了新的字符數組復制於傳入的數組,將這個新數組賦值給value屬性。

直到這為止我對String不可變這個概念也有了一個比較清晰的認識了。

StringBuffer源碼比較復雜一點,但是由於是可變類型,可以把它理解為普通實體類擁有一個非fina屬性即可。

 

String對象和StringBuffer對象轉字符數組

String類型:

    String str = "abc";
        //1.直接調用String對象的toCharArray()方法就可以得到該字符數組
        char[] chars = str.toCharArray();

        //2.調用String對象的getChars()方法,
        char values_1[] = new char[str.length()];
        str.getChars(0,str.length(),values_1,0);

        //3.遍歷
        char values_2[] = new char[str.length()];
        for (int i=0;i<str.length();i++){
            values_2[i] = str.charAt(i);
        }

        //4.調用String對象的split()方法,
        String[] split = str.split("");

其中第四個方法是轉換成了String類型的數組

String類型轉char類型(String對象值為一個字符時)

String c1 = "a";
char c2 = c1.charAt(0);

StringBuffer類型:

StringBuffer sb = new StringBuffer("abc");
        
//1.StringBuffer的getChars()方法
char sbValues_1[] = new char[sb.length()];
sb.getChars(0,sb.length(),sbValues_1,0);
        
//2.遍歷
char sbValues_2[] = new char[sb.length()];
for (int i=0;i<sb.length();i++){
     sbValues_2[i] = sb.charAt(i);
}

其中String和StringBuffer的getChars()方法,下面是官方文檔介紹

注:如果字符數組長度小於StringBuffer類對象剪切的字符串長度,會出現數組下標超出邊界異常


StringBuffer (Java Platform SE 8 ) public void getChars(int srcBegin,
 int srcEnd,
 char[] dst,
 int dstBegin)
字符從該序列復制到目標字符數組dst 。 要復制的第一個字符是索引srcBegin ; 要復制的最后一個字符在索引srcEnd-1 。 
要復制的srcEnd-srcBegin總數為srcEnd-srcBegin 。 字符被復制到的子陣列dst開始於索引dstBegin和在索引結束: StringBuffer (Java Platform SE 8 ) 參數 srcBegin - 以此偏移開始復制。 srcEnd - 在此偏移處停止復制。 dst - 將數據復制到的數組。 dstBegin - 偏移到 dst 。

 

以上就是這篇隨筆的所有內容,由於這是本人開通博客寫的第一篇隨筆,而且我自己目前也只是個初學者,所以上面難免有很多不嚴謹和錯誤的地方,請大家多多指正,大家一起學習,謝謝大家。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM