- 基本數據類型
- 整型: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---worldchange(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---worldchange(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類 在做運算的時候,對操作符進行了重載。