基本類型參數傳遞java
public class Test1 { public static void main(String[] args) { int n = 3; System.out.println("Before change, n = " + n); changeData(n); System.out.println("After changeData(n), n = " + n); } public static void changeData(int nn) { n = 10; } }
基本類型做爲參數傳遞時,是傳遞值的拷貝,不管你怎麼改變這個拷貝,原值是不會改變的,輸出的結果證實了這一點:app
Before change, n = 3 After changeData(n), n = 3
類對象參數傳遞code
public class Test2 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After changeData(n), sb = " + sb); } public static void changeData(StringBuffer strBuf) { strBuf.append("World!"); } }
輸出結果:對象
Before change, sb = Hello After changeData(n), sb = Hello World!
從結果來看,sb的值被改變了,對象做爲參數傳遞時,是把對象的引用傳遞過去,若是引用在方法內被改變了,那麼原對象也跟着改變。從上面例子的輸出結果來看,這樣解釋是合理。內存
如今咱們改動一下:class
public class Test3 { public static void main(String[] args) { StringBuffer sb = new StringBuffer("Hello "); System.out.println("Before change, sb = " + sb); changeData(sb); System.out.println("After changeData(n), sb = " + sb); } public static void changeData(StringBuffer strBuf) { strBuf = new StringBuffer("Hi "); strBuf.append("World!"); } }
按照上面例子的經驗:對象做爲參數傳遞時,是把對象的引用傳遞過去,若是引用在方法內被改變了,那麼原對象也跟着改變。你會認爲應該輸出:引用
Before change, sb = Hello After changeData(n), sb = Hi World!
但運行一下這個程序,你會發現結果是這樣的:程序
Before change, sb = Hello After changeData(n), sb = Hello
這就是讓人迷惑的地方,對象做爲參數傳遞時,一樣是在方法內改變了對象的值,爲何有的是改變了原對象的值,而有的並無改變原對象的值呢?這時候到底是「傳值」仍是「傳引用」呢?方法
Test2中 StringBuffer sb = new StringBuffer("Hello "); 這一句執行完後,就會在內存的堆裏生成一個sb對象。sb指向堆裏的"Hello"。im
changeData(sb);執行這一句後,就把sb傳給了changeData方法中的StringBuffer strBuf,因爲sb指向"Hello",因此,strBuf也指向"Hello"。
strBuf.append("World!");執行這一句後,改變了strBuf指向的內存中的值。
因此,Test2 這個程序最後會輸出:After changeData(n), sb = Hello World!
Test3中在沒有執行到changeData方法的strBuf = new StringBuffer(「Hi 「);以前,和Test2是同樣的,而執行了strBuf = new StringBuffer(「Hi 「);以後,此時,strBuf中存放的再也不是指向「Hello」的地址,而是指向「Hi 」的地址了,new操做符操做成功後總會在內存中新開闢一塊存儲區域。
strBuf.append("World!");而執行完這句後,因爲sb和strBuf中存放地址不同了,因此雖然strBuf指向的內存中的值改變了,但sb指向的內存中值並不會變,所以也就輸出了下面的結果:After changeData(n), sb = Hello
從如下這個例子中,你們就能夠直觀的看出區別:
注意:String類是個final類型的,你改變它的值就至關於從新new了,如:
String str = "haha"
str = 「Hello」; 等價於String str = new String(「Hello」);
String str = 「Hello」; str = str + 「 world!」;等價於str = new String((new StringBuffer(str)).append(「 world!」)); 所以,你只要按上面的方法去分析,就會發現String對象和基本類型同樣,通常狀況下做爲參數傳遞,在方法內改變了值,而原對象是不會被改變的。