java參數傳遞

基本類型參數傳遞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對象和基本類型同樣,通常狀況下做爲參數傳遞,在方法內改變了值,而原對象是不會被改變的。

相關文章
相關標籤/搜索