java方法參數和C方法參數的區別 – JAVA編程語言程序開發技術文章

方法調用(call by) 是一個標準的計算機科學術語。方法調用根據參數傳遞的情況又分為值調用( call by reference ) 和引用調用( call by value ) 。江湖上有很多關於這兩種調用的定義 ,最通常的說法是傳遞值的是值調用,傳遞地址的是引用調用。這其實很不恰當,這種 這些說法很容易讓我們聯想到Java的對象參數傳遞是引用調用,實際上,Java的對象參數傳遞仍然是值調用 。
我們首先用一段代碼來證實一下為什麼Java的對象參數傳遞 是值調用。

public class Employee {  
 
    public String name=null;  
      
    public Employee(String n){  
        this.name=n;  
    }  
    //將兩個Employee對象交換  
    public static void swap(Employee e1,Employee e2){  
        Employee temp=e1;  
        e1=e2;  
        e2=temp;  
                System.out.println(e1.name+" "+e2.name); //打印結果:李四 張三  
    }  
    //主函數  
    public static void main(String[] args) {  
        Employee worker=new Employee("張三");  
        Employee manager=new Employee("李四");  
        swap(worker,manager);  
        System.out.println(worker.name+" "+manager.name); //打印結果仍然是: 張三 李四  
    }  

上面的結果讓人很失望,雖然形參對象e1,e2的內容交換瞭,但實參對象worker,manager並沒有互換內容。這裡面最重要的原因就在於形參e1,e2是實參worker,manager的地址拷貝。

      大傢都知道,在Java中對象變量名實際上代表的是對象在堆中的地址(專業術語叫做對象引用 )。在Java方法調用的時候,參數傳遞的是對象的引用。重要的是,形參和實參所占的內存地址並不一樣,形參中的內容隻是實參中存儲的對象引用的一份拷貝。 java多線程下載網絡資源

       如果大傢對JVM內存管理中Java棧 的局部變量區 有所瞭解的話(可以參見《 Java 虛擬機體系結構 》),就很好理解上面這句話。在JVM運行上面的程序時,運行main方法和swap方法,會在Java棧中先後push兩個叫做棧幀 的內存空間。main棧幀中有一塊叫局部變量區的內存用來存儲實參對象worker和manager的引用。而swap棧幀中的局部變量區則存儲瞭形參對 象e1和e2的引用。雖然e1和e2的引用值分別與worker和manager相同,但是它們占用瞭不同的內存空間。當e1和e2的引用發生交換時,下 面的圖很清晰的看出完全不會影響worker和manager的引用值。
          
      Java對象參數傳遞雖然傳遞的是地址(引用),但仍然是值調用。是時候需要給引用調用和值調用一個準確的定義瞭。

      值調用(call by value) : 在參數傳遞過程中,形參和實參占用瞭兩個完全不同的內存空間。形參所存儲的內容是實參存儲內容的一份拷貝。實際上,Java對象的傳遞就符合這個定義,隻 不過形參和實參所儲存的內容並不是常規意義上的變量值,而是變量的地址。咳,回過頭想想:變量的地址不也是一種值嗎!

      引用調用(call by reference) : 在參數傳遞的過程中,形參和實參完全是同一塊內存空間,兩者不分彼此。 實際上,形參名和實參名隻是編程中的不同符號,在程序運行過程中,內存中存儲的空間才是最重要的。不同的變量名並不能說明占用的內存存儲空間不同。
      大體上說,兩種調用的根本並不在於傳遞的是值還是地址(畢竟地址也是一個值),而是在於形參和實參是否占用同一塊內存空間。事實上,C/C++的指針參數傳遞也是值調用,不信試試下面的C代碼吧!

#include<stdio.h>  
void swap(int *a1,int *b1){   EMS指南
    int *t=a1;  
    a1=b1;  
    b1=t;  
}  
int main(){  
    int x1=100;  
    int x2=200;  
        int *a=&x1;  
    int *b=&x2;  
    printf("%d %d\n",*a,*b);  
    swap(a,b);  
    printf("%d %d\n",*a,*b);  
    return 0;  

作者“墻頭草的博客”

發佈留言