java (值傳遞和引用傳遞) String 和StringBuffer 作爲參數傳遞

首先,java中有這兩種類型數據。
  • 基本數據類型 
    • 整型:byte,short,int,long
    • 浮點型:float,double
    • 字符型:char
    • 布爾型:boolean
  • 引用數據類型 
    • 數組
    • 對象(類、接口)

一般情況下,基本數據類型傳遞時是值傳遞,引用數據類型是引用傳遞。

而String有些不一樣,它是字符串對象,既然是對象,傳遞應該是引用傳遞,但是實際卻不一樣。

直接看例子。

  public static void main(String[] args){
  String s1 = "hello";

  String s2 = "world";

  System.out.println(s1+"---"+s2); //hello---world  
  change(s1,s2);
  System.out.println(s1+"---"+s2); //hello---world

  StringBuffer sb1 = new StringBuffer("hello");  

  StringBuffer sb2 = new StringBuffer("world");

  System.out.println(sb1+"---"+sb2);//hello---world
  change(sb1,sb2);
  System.out.println(sb1+"---"+sb2);//***hello---worldworld

   }

  private static void change(StringBuffer sb1,StringBuffer sb2){
          sb1 = sb2;
          sb2.appned(sb1);
  }
  public static void change(String s1,String s2){
          s1 = s2;
          s2 = s1+s2;

   }

可以看出,String 的本質卻是值傳遞,而StringBuffer是引用傳遞

再看看String內部代碼。


                                                                                                                               (借鑑的某圖)

 可以看出,其內部存儲值得變量用了final修飾,所以也是常說的String的值不可變

 但是,測試一下,可以發現。

String str = "ab";

String str = "abcd";

而這兩行代碼卻不會報錯,可以說是str的值被改變了。

但實際上卻是,新建了一個名爲"abcd"的字符串放在了常量池中,讓str指向了它,而常量池中還有個"ab",這個"ab"是str原本引用的值,它並沒有任何的改變。

並不是說str的值被改變了,而是它引用的地址被改變了,String是個對象類型,也有這種原因。

所以最開始的例子,說它是對象,對象是引用傳遞,這並沒有錯,可實際上它是值傳遞,爲什麼

在參數傳遞中,Stirng 實參地址 傳給了 形參 ,形參有了地址,在change方法中,它在做運算的時候(s2 = s1+s2) 卻新建了一個字符串"helloworld" 放在常量池中,再加上之前的兩個(s1,s2),一共有三個地址。change方法中的s2指向"helloworld",但主方法中的s1、s2依然指向的原來的地址("hello"、"world"),其中的內容沒有任何的改變,所以說是值傳遞。

而StringBuffer,實參地址 傳給了 形參 ,形參有了地址,在change方法中,它在做運算的時候,沒有新建字符串,在常量池中還是隻有兩個地址,StringBuffer是直接就在s2的地址上的值進行修改。

爲什麼String會在做運算的時候會新建字符串呢?

這是因爲String類 在做運算的時候,對操作符進行了重載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章