Java中隻有按值傳遞,沒有按引用傳遞!
方法參數共有兩種類型:
- 基本資料類型
- 對象引用
一:基本資料類型
首先看一個小例子:
1 package chuandi;
2
3 public class Test1 {
4 public static void main(String[] args) {
5 int x=8;
6 change(x);
7 System.out.println(x);
8 }
9 public static void change(int b){
10 b=b*2;
11 }
12 }
如果按引用傳遞,那麼得到的值應該是:16 ,但是答案卻是

可以看到x的值并沒有發生變化;
過程是這樣的:
- b被初始化為x值的一個拷貝,即8
- b乘以2後等于16。但是x沒有變化,依然是8
- change執行完後,參數變量不再使用
x作為參數傳遞給change()方法時,是将記憶體空間中x所指向的那個存儲單元中存放的值,即"8",傳送給了change()方法中的b變量,而這個b變量也在記憶體空間中配置設定了一個存儲單元,這個時候,就把x的值8傳送給了這個存儲單元中。此後,在change()方法中對b的一切操作都是針對b所指向的這個存儲單元,與x所指向的那個存儲單元沒有關系了!
自然,在函數調用之後,x所指向的存儲單元的值還是沒有發生變化,這就是所謂的“值傳遞”!值傳遞的精髓是:傳遞的是存儲單元中的内容,而非位址或者引用!
二:對象引用
1 package chuandi;
2
3 public class Test2 {
4 public static String name = "hello";
5 public void change(Test2 t){
6 t.name="hi";
7 }
8
9 public static void main(String[] args) {
10 Test2 t=new Test2();
11 System.out.println(t.name);
12 t.change(t);
13 System.out.println(t.name);
14 }
15 }
那麼既然是按值傳遞,為什麼還能改變對象裡面的值???請看下面;
運作流程:
首先在main方法中我們建立了Test的對象,(了解堆棧了後面是容易了解的),實際Test對象被建立在堆中,在棧中又建立Test類型的t,這是一個句柄,裡面存放的是Test對象在堆中的實際位置;然後運作到change()方法,我們将t這個參數傳進方法,t裡面存放的是實際Test的位置,也就是Test存儲單元,也就是說在change()方法中對t的一切操作都是針對t所指向的這個存儲單元;(t所指向的那個存儲單元中的内容是實體對象的位址,使得t也指向了該實體對象,是以才能改變對象内部的屬性!這也是我們大多數人會誤以為是“引用傳遞”的終極原因!!!)回顧一下上面的一個值傳遞的例子,值傳遞,就是将存儲單元中的内容傳給調用函數中的那個參數,這裡是不是異曲同工,是所謂“值傳遞”,而非“引用傳遞”!!!
歡迎大家一起說出自己的想法。