對於java中的值傳遞和引用傳遞一直頗受爭論,《Core Java》的作者,以及JAVA的創造者James Gosling都認為當一個對象或引用類型變量被當作參數傳遞時,也是值傳遞,這個值就是對象的引用,因此JAVA中只有值傳遞,沒有引用傳遞。還有一種說法是引用可以看作是對象的別名,當對象被當作參數傳遞給方法時,傳遞的是對象的引用,因此是引用傳遞。而《Thinking in Java》一書的作者Bruce Eckel則站在了中立的立場上。
大都數人其實都傾向於第一種說法,java中沒有引用傳遞,本人也更傾向於第一種解釋,下面講講個人的見解。
首先明白幾個概念,什么是值傳遞,引用傳遞和指針傳遞?特別注意一下引用傳遞的概念,這個最早應該是出現在c++中,c中沒有這個概念,c只有值傳遞和指針傳遞。
值傳遞:傳遞實參的一個復本給形參,在被調函數內對形參的修改不會影響到原來的實參
引用傳遞(c++中的定義):形參相當於是實參的“別名”,對形參的操作其實就是對實參的操作,在引用傳遞過程中,被調函數的形參雖然也作為局部變量在棧中開辟了內存空間,但是這時存 放的是由主調函數放進來的實參變量的地址。被調函數對形參的任何操作都被處理成間接尋址,即通過棧中存放的地址訪問主調函數中的實參變量。正因為如此,被調函數對形參做的 任何操作都影響了主調函數中的實參變量。
指針傳遞:本質還值傳遞,把指針的值復制一份傳遞給形參,都指向實參指針指向的值,當對形參指向的內容操作時,就相當於對實參本身進行的操作。
其實引用傳遞和指針傳遞的實質是一樣的,從匯編層面是無法區別兩者的,引用是C++對指針的一種封裝,方便使用,其實質和指針引用一樣。糾正一下C++程序設計(譚浩強)中的一個問題,書上介紹引用的地方第198頁說引用不是一個獨立的變量,不單獨占內存單元,這個說法不嚴謹,引用類型的參數也要占用內存空間的,保存的數據是一個地址。
再來看看Java中所謂的引用傳遞,其實和c++中的指針傳遞是一樣的,指針傳遞的本質是值傳遞,所以可以說java中沒有引用傳遞。
附一道面試題,來測試下對上面的理解,寫出程序運行結果!
public class TestMain { /** * @author lcq * @date 2013-4-8 * @param args */ public static void main(String[] args) { String a = "a"; String b = "b"; operator(a, b); StringBuilder x = new StringBuilder("x"); StringBuilder y = new StringBuilder("y"); operator(x, y); System.out.println(a + "," + b); System.out.println(x + "," + y); } public static void operator(String a, String b) { a += b; b = a; } public static void operator(StringBuilder a, StringBuilder b) { a.append(b); b = a; } }
正確的答案是
a,b
xy,y
你,答對了嘛?