一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java方法參數是引用調用還是值調用?

Java方法參數是引用調用還是值調用?

2020-04-06 11:24lijiao JAVA教程

Java方法參數是引用調用還是值調用?,這是一個值得思考的問題。閱讀本文,找出答案

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

我們首先用一段代碼來證實一下為什么Java的對象參數傳遞是值調用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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方法調用的時候,參數傳遞的是對象的引用。重要的是,形參和實參所占的內存地址并不一樣,形參中的內容只是實參中存儲的對象引用的一份拷貝。

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

Java方法參數是引用調用還是值調用?

Java對象參數傳遞雖然傳遞的是地址(引用),但仍然是值調用。是時候需要給引用調用和值調用一個準確的定義了。

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

引用調用(call by reference) : 在參數傳遞的過程中,形參和實參完全是同一塊內存空間,兩者不分彼此。 實際上,形參名和實參名只是編程中的不同符號,在程序運行過程中,內存中存儲的空間才是最重要的。不同的變量名并不能說明占用的內存存儲空間不同。

大體上說,兩種調用的根本并不在于傳遞的是值還是地址(畢竟地址也是一個值),而是在于形參和實參是否占用同一塊內存空間。事實上,C/C++的指針參數傳遞也是值調用,不信試試下面的C代碼吧!

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<stdio.h>
void swap(int *a1,int *b1){
  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;
}

但C/C++是有引用調用的,這就是C/C++一種叫做引用的變量聲明方法: int a; int &ra=a; 其中ra是a的別名,兩者在內存中沒有區別,占用了同一個內存空間。而通過引用(別名)的參數傳遞就符合引用調用的特點了。大家可以去試試void swap(int &a1,int &b1);的運行結果。

通過本文大家應該知道Java方法參數是引用調用還是值調用了吧。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 性做久久久久久久久浪潮 | 亚洲一卡2卡4卡5卡6卡残暴在线 | 99re5在线精品视频热线 | 亚洲国产精品久久丫 | 亚洲午夜久久久久国产 | 网友自拍咪咪爱 | 成人国产第一区在线观看 | 3d动漫美女被吸乳羞羞有 | 久久热在线视频精品店 | 日韩乱淫 | 99re思思| 四虎成人免费大片在线 | 日本成熟老妇xxxx | 四川女人偷人真实视频 | 欧美一区二区三区免费观看视频 | 女同性互吃奶乳免费视频 | bbbxxx乱大交欧美小说 | 搡60一70岁的老女人小说 | 天天综合天天综合色在线 | 美国大片成人性网 | 麻豆在线md0087免费 | 亚洲精品国产一区二区三区在 | 亚洲精品一区二区三区在线看 | 日韩成人免费aa在线看 | 国产拍拍拍免费专区在线观看 | 果冻传媒在线视频观看免费 | 性xxxx中国老妇506070 | 岛国片免费观看 | 91香蕉小视频 | 国产精品视频在线观看 | 香蕉久久久久 | 欧美z0z0人禽交 | 欧美不卡一区二区三区 | 亚洲卡一卡2卡三卡4卡无卡三 | 亚洲国产精品成人综合久久久 | 欧美在线播放成人免费 | 日本在线不卡免 | gayrb漫画免费入口 | 免费视频专区一国产盗摄 | 古装一级无遮挡毛片免费观看 | 午夜福利理论片高清在线 |