Java究竟是按值傳遞仍是按引用傳遞?

今天刷牛客網的題,其中一題是這樣的html

 1 public class Test1 {
 2 
 3     public static void main(String[] args) {
 4         Test1 t1 = new Test1();
 5         t1.first();
 6     }
 7     
 8     public void first(){
 9         int i = 5;
10         Value v = new Value();
11         v.i = 25;
12         second(v, i);
13         System.out.println(v.i + " " + i);
14     }
15     
16     public void second(Value v, int i){
17         i = 0;
18         v.i = 20;
19         Value val = new Value();
20         v = val;
21         System.out.println(v.i + " " + i);
22     }
23 }
24 
25 class Value {
26     public int i = 15;
27 }

最終輸出是:15  0  20spa

 

我覺得的輸出是:15  0  15code

個人疑問在於第20行。htm


 

從上面引起了一個問題,Java究竟是按值傳遞仍是按引用傳遞?blog

之前,認爲是值傳遞,是經過一個簡單的swap例子class

 1     public static void main(String[] args) {
 2         int a = 10;
 3         int b = 20;
 4         swap(a, b);
 5         System.out.println("此時a爲: " + a);
 6         System.out.println("此時b爲: " + b);
 7     }
 8 
 9     public static void swap(int x, int y){
10         int temp = x;
11         x = y;
12         y = temp;
13         System.out.println("此時x爲: " + x);
14         System.out.println("此時y爲: " + y);
15         System.out.println();
16     }

結果爲:變量

此時x爲: 20
此時y爲: 10

此時a爲: 10
此時b爲: 20

若是是按引用傳遞,那麼結果就不會這樣。搜索

但是,牛客網上的那道題又把我繞進去了。翻了翻該題的評論,大部分都說是值傳遞,可是仍然有人說提出引用傳遞的疑問。引用

 

不得已,翻書,Java核心技術卷1 第十版  page118~121方法

還有,搜索相關話題


 

結論:Java按值傳遞

總結:

  方法獲得的是全部參數值的一個拷貝,特別是,方法不能修改傳遞給它的任何參數變量的內容。

解釋:

    不管方法的形參中放的是基本類型參數,仍是引用類型參數,方法獲得的永遠只是一個拷貝或者副本。

    因此,上面的swap例子中,swap方法的形參  x、y  只是一個原始參數的副本,可是他們的值都是同樣的。

    此時,我在swap方法裏改變了  x、y 的值,也只是改變了副本的值,對原始值沒有任何影響

 

    而對於引用參數的傳遞,傳遞的仍然是引用參數的副本,只不過這個副本里放的是參數的地址,也就是說,他們此時指向了同一個地址

    若是此時副本改變了此地址中的值,那麼相應的引用參數所存的值也會被改變

 

    但是,爲何牛客網試題,第20行執行後,v 已經指向了 val,而 val 中 i 的值爲15,最終first方法中輸出的倒是20呢?

    由於 -- 當第20行還未執行時,v.i = 20, 此時 i 的值變爲20,first方法中的 v 和 second 中形參的 v 仍是指向同一地址的,

    可是第20行執行事後,second 中的 v 已經指向 了一個新的地址,也就是 val 指向的地址,

    那麼, 這時候 second 中的 v 已經和 first 中的 v 斷掉了聯繫,二者已經屬於你走東,我走西,各無瓜葛的狀態

    因此,在後面 second 中的 v 你怎麼樣變,都影響不了本來的引用參數。

    小結這段話:做爲引用參數副本,只要後期不從新指向一個新的地址,那麼副本改變指向地址中的值,引用參數中的值也會被改變


 

相關連接:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html

相關閱讀:Java核心技術 卷1 第十版  Page118~121

相關文章
相關標籤/搜索