java引用传递106_(转载)java的值传递与引用传递
1 說明:本文的適用對象為java初學者、如果有讀者發現文章中有敘述不妥之處,請指正。2
3 今天在論壇上有人提了一個關于java中調用函數時有沒有引用傳遞的問題,可謂是吵的不可開交。有人說java只有值傳遞,也有人說java既有值傳遞也有引用傳遞,那么java中到底有沒有引用傳遞呢,下面我來分析一下。4
5 一、首先來明確一下"值傳遞"和"引用傳遞的"區別6
7 值傳遞:是對所傳遞參數進行一次副本拷貝,對參數的修改只是對副本的修改,函數調用結束,副本丟棄,原來的變量不變(即實參不變)8 引用傳遞:參數被傳遞到函數時,不復制副本,而是直接將參數自身傳入到函數,函數內對參數的任何改變都將反映到原來的變量上。9 二、java中引用的含義10
11 C++和java中都有引用的概念,但在這兩種語言中卻有完全不同的含義。C++中我們可以用形如"int &b=a”的形式來定義變量a的一個引用b,b只是a的一個別名,b和a在內存中占同一個存儲單元,利用引用機制我們可以在調用函數時實現值的雙向傳遞——即引用傳遞,看下面代碼:
12
13 示例一14
15 #include
16
17 using namespace std;18
19 intmain()20
21 {22
23 void swap(int &,int &);24
25 int i=3,j=5;26
27 swap(i,j);28
29 cout<
31 return 0;32
33 }34
35
36
37 void swap(int &a,int &b)38
39 {40
41 inttemp;42
43 temp=a;44
45 a=b;46
47 b=temp;48
49 }50
51 執行上面的程序輸出的是i=5 j=3,a和b傳遞給swap()函數的時候,是傳遞的他們本身的地址,不是他們的拷貝,所以在函數中對他們的改變可以直接影響到實參a和b,這就是引用傳遞。52
53 java中的引用更像C++中的指針,當我們定義一個對象時(比如Person p=newPerson()),定義的對象實例會放到java堆中,而變量p(即引用)會放到java棧中,p指向堆中的Person對象實例。54
55 三、對引用傳遞的認識誤區56
57 為什么有很多人認為java有引用傳遞呢?一種情況是有人認為調用函數時其參數有可能是引用(如上面的p),所以java有引用傳遞,這部分人對引用傳遞根本沒有正確的認識;而另一種情況看似有道理,但是仔細分析也是不正確的的,他們往往會用如下的代碼來證明他們的觀點:58
59 實例二:60
61 復制代碼62 classDemo{63 inta;64 public Demo(inta){65 this.a=a;66 }67 }68 public classTestQuote{69 public static voidmain(String args[]){70 Demo d1=new Demo(1);71 Demo d2=new Demo(2);72 System.out.println(d1.a);73 System.out.println(d2.a);74 function(d1,d2);75 System.out.println(d1.a);76 System.out.println(d2.a);77 }78 private static voidfunction(Demo d1,Demo d2){79 inta;80 a=d1.a;81 d1.a=d2.a;82 d2.a=a;83 }84 }85 復制代碼86 他們的觀點如下:執行上面的代碼,調用function()函數以前輸出的結果是1、2,調用function()函數之后輸出的結果會是2、1,可見在函數內對d1和d2的改變反映到了原來的變量上,要不是不會輸出2、1的。87
88 這種解釋是很迷惑人的,看上去好像很正確,下面的代碼會很好的反駁上面的觀點:89
90 示例三:91
92 復制代碼93 classDemo{94 inta;95 public Demo(inta){96 this.a=a;97 }98 }99 public classTestQuote{100 public static voidmain(String args[]){101 Demo d1=new Demo(1);102 Demo d2=new Demo(2);103 System.out.println(d1.a);104 System.out.println(d2.a);105 function(d1,d2);106 System.out.println(d1.a);107 System.out.println(d2.a);108 }109 private static voidfunction(Demo d1,Demo d2){110 Demo temp;111 temp=d1;112 d1=d2;113 d2=temp;114 }115 }116 復制代碼117 執行上面的代碼,調用function()前后程序輸出的都是1、2,此程序試圖通過調用function()交換d1和d2,但是沒有成功,為什么呢?因為d1和d2是值傳遞,function()中的d1和d2是main()函數中d1和d2的副本,調用完function()不會對main()中的變量產生影響。再看示例二中,function()函數內改變的并不是d1和d2本身的值,而是d1和d2指向的對象的值,調用完function()后d1和d2仍然指向函數調用前的堆地址,即函數參數是棧中的d1和d2,而不是堆中d1和d2指向的對象,即使你在函數中改變了堆中的對象,但沒有改變函數參數的值。所以示例二并不是什么引用傳遞;可見java中只有值傳遞。118
119
120
121 但是網上有很多針對"java值傳遞和引用傳遞進行的區別"的文章,如果讀者看到的話一定要清楚,其中所說的引用傳遞是不正確的,他們所說的引用傳遞就是示例二中的那種情況。不幸的是,網上有很多文章都把示例二中的那樣的傳遞看做引用傳遞,如果讀者看到知道是什么意思就行了。
總結
以上是生活随笔為你收集整理的java引用传递106_(转载)java的值传递与引用传递的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用Java 编写菜单价格和的程序_使用J
- 下一篇: Win10虚拟机无法连接网络怎么解决 W