1. 程式人生 > >Java中的值傳遞和地址傳遞

Java中的值傳遞和地址傳遞

0.前言

被java中的“值傳遞”和“引用傳遞”困擾過一陣子,在實際程式碼中也犯過不少錯,記錄一下,方便檢視。

1.問題

首先看看程式碼:

public class Test {
     public static void main(String[] args) {
            String str = "123";
            System.out.println(str);
            change(str);
            System.out.println(str);
        }
    public static
void change(String str){ str = "456"; } }

那麼你覺得會輸出多少呢?至少我曾經覺得是:

123
456

但是,正確答案是:

123
123

這是為什麼呢?我相信答錯的同學大都是受到了一些”java教材“的影響–java的引數傳遞有兩種:

  1. 值傳遞,傳遞值,在函式中形參發生的變化不影響實參。
  2. 引用傳遞,傳遞物件引用,在函式中形參發生的變化影響實參。

然而,實際上java引數傳遞只有一種情況,那就是值傳遞。所不同的是,一般說的”引用傳遞”,在實際中傳遞的不過是引用物件的地址值

在解釋上述程式碼前,先要在補充一點知識:

String a = new String("123");
String b;
b= new String("123");

兩種形式的程式碼所形成的的結果是完全一致的,後面一種更容易理解java中的引用與物件的具體含義。先宣告一個String物件的引用,再new一個“123”物件,最後將這個物件賦值(等號=)給該引用

  1. b:物件的引用
  2. “123”:實際物件

好了,現在來具體解釋一下值傳遞地址值引用吧。

1.值

int a = 1;
void f(int b){
  b =2;
}

a是多少呢?肯定是1嘛。

image.png

將a的值1傳遞給b,b的值為1.這樣不論b如何更改,並不影響a的值。

2.地址值

String a = new String("123";)
void main(String b){
  b = new String("345");
}

image.png
首先,a將物件“123”的地址值傳遞給b,b指向”123”的地址

之後 new了一個”345”物件,b重新指向了”345”,也就是下圖。
image.png
所以,僅僅是b的引用物件發生了變化,a的引用物件毫無改變。
**現在能夠解釋文首的問題了。**But,there is one more thing.

如下程式碼:

public class Test {
     public static void main(String[] args) {
         StringBuilder a = new StringBuilder("123");
         change(a);
         System.out.println(a);
        }
    public static void change(StringBuilder str){
            str.append("345");
    }
}

現在,a的值是多少?

答案是:

123345

這也就是平常我們所理解的,傳遞“引用”會影響原物件本身。還是畫個圖來解釋:
image.png

首先a將“123”物件的地址傳遞給b,b指向“123”,接著通過“綠色”引用改變了“123”物件。因為a也是指向“123”物件,所以輸出a也變為了”123345”。

That’s all.Hope you have understood。