天天看點

JAVA中的按值傳遞

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 ,但是答案卻是

JAVA中的按值傳遞

可以看到x的值并沒有發生變化;

過程是這樣的:

  1. b被初始化為x值的一個拷貝,即8
  2. b乘以2後等于16。但是x沒有變化,依然是8
  3. 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 }      
JAVA中的按值傳遞

那麼既然是按值傳遞,為什麼還能改變對象裡面的值???請看下面;

 運作流程:

   首先在main方法中我們建立了Test的對象,(了解堆棧了後面是容易了解的),實際Test對象被建立在堆中,在棧中又建立Test類型的t,這是一個句柄,裡面存放的是Test對象在堆中的實際位置;然後運作到change()方法,我們将t這個參數傳進方法,t裡面存放的是實際Test的位置,也就是Test存儲單元,也就是說在change()方法中對t的一切操作都是針對t所指向的這個存儲單元;(t所指向的那個存儲單元中的内容是實體對象的位址,使得t也指向了該實體對象,是以才能改變對象内部的屬性!這也是我們大多數人會誤以為是“引用傳遞”的終極原因!!!)回顧一下上面的一個值傳遞的例子,值傳遞,就是将存儲單元中的内容傳給調用函數中的那個參數,這裡是不是異曲同工,是所謂“值傳遞”,而非“引用傳遞”!!!

歡迎大家一起說出自己的想法。