java中參數傳遞的方式

來源:互聯網
上載者:User

今天在寫代碼的時候遇到了一個參數傳遞的問題,雖然我知道問題出現在哪裡,但是問題的原因似懂非懂,看了很久之前寫的一篇部落格,在網上搜尋了幾篇文章

看了下,終於徹底弄懂了這個問題的原因,寫篇文章總結下。

首先我們得明白幾個概念:按值傳遞,按引用傳遞,棧記憶體,堆記憶體的區別。

一按值傳遞:按值傳遞傳遞的是數值,傳遞的時候會在記憶體中另開闢一塊空間來儲存這個數值,如:

public static void main(String[] args){double a = 3.0;double b = 3.0;Test test = new Test();test.play(a,b);System.out.println("a:"+a);System.out.println("b:"+b);}public void play(double a,double b){a = 0.0;b = 0.0;}

transformLon這個函數中的參數就是按值傳遞的,a,b傳遞進去後會在記憶體中另開闢一塊記憶體空間來儲存a,b的值,所以函數裡面對a,b的更改不會引起函數外面a,b值的改變

a,b列印出來後的結果為: 可以看出a,b的值並未改變。

二按引用傳遞:按引用傳遞其實也是可以理解為按值傳遞,只不過他這個值不是直接的數值,而是儲存數值的地址,但是我們操作修改的卻是數值,而不是地址

故按值傳遞時,會改變前面傳過來的對象。如:

public static void main(String[] args){String array[] = new String[]{"hello world"};Test test = new Test();System.out.println("調用play方法前的array[0]:"+array[0]);test.play(array);System.out.println("調用play方法後的array[0]:"+array[0]);}public void play(String array[]){array[0] = "gaga";}

我們來看一下列印的結果: 可以看出array[0]的值在調用play方法前後是不一樣的,與前面的按值傳遞效

果相反。

三棧記憶體和堆記憶體:

棧記憶體是用來儲存儲存基礎資料型別 (Elementary Data Type)的資料和引用變數及對象。java中的基礎資料型別 (Elementary Data Type)的數值都是儲存在棧中,程式員不能夠直接的設定堆或棧。棧的主要優點為存取

速度快,缺點為存在於棧的資料大小和生存周期是確定的,缺乏靈活性。堆用於存放所有由new關鍵字所建立對象指向的數值的地址,並不是這個對象的地址。如:

由new 所建立的封裝資料類型,Double,String 等 對象的數值則是儲存在堆中。在堆中分配的記憶體由java虛擬機器的記憶體回收行程(Garbage Collection)GC自動回收。

具體棧和堆的區別可以去看一下我之前寫的一篇文章:java中堆和棧的區別。

介紹了完了按值傳遞,按應用傳遞以及棧記憶體和堆記憶體之後,我們從記憶體方面來分析按值傳遞和按引用傳遞的區別。

首先我們看一下按值傳遞時,代碼的記憶體模型圖:

 

我們看一下按值傳遞時,a的記憶體模型的變遷,可以看出當 定義 doube a = 3.0;時程式會在棧記憶體中分配一塊空間,將數值3.0儲存在這塊空間中,當將a 作為參數傳遞

給play方法時,程式會在記憶體中另外開闢一塊空間A,用來儲存a的數值3.0,當在方法play中對參數a進行了修改,a的值並未改變,改變的是A記憶體中的數值,他由3.0變

成了0.0。A中記憶體的數值和a中記憶體的數值沒有任何關係。

上面就是按值傳遞的原理。

接下來我們來瞭解一下,按引用傳遞時,代碼的記憶體模型:

我們看下按引用傳遞時的記憶體模型,瞭解引用傳遞時的記憶體模型就必須瞭解棧記憶體和堆記憶體,之前已經介紹過了,就不在這裡在贅述了。從這個模型我們可以知道

當new 出Array數組時,會在棧記憶體中分配一地區,array數組有多少個元素就會分配多少塊地區 。假設array[0]對象分配的是“地址a”,array[0]的數值則是在堆記憶體

中開闢了一塊地區用於儲存,當array[0]作為參數傳遞到play方法當中時,程式會在棧記憶體中分配一塊地區儲存array[0]對象(不是array[0]的數值,堆記憶體中只能通過

new 關鍵字來開闢地區)即:地址a,當我們在play方法中修改array[0]對象的數值時,其實是修改堆中儲存的數值,而不是array[0]對象。於是堆中的數值由gaga被

改變為hello world,於是當我們列印出array[0]修改前後的數值時,可以看出已經改變了。這就是按引用傳遞時的原理。

按引用傳遞,其實也是按值傳遞,只不過他傳遞的是數值的地址,而不是數值。我們只要記住,凡是通過new關鍵字建立出來的對象,進行傳遞時都是按引用傳遞

基礎資料型別 (Elementary Data Type)的傳遞都是按值傳遞。按應用傳遞傳遞的是棧中的地址,按值傳遞傳遞的是棧記憶體中的值,這就是按值傳遞和按引用傳遞的主要區別。

 參考資料:

http://www.shaccp.com/azxxx/2012/2005.html

http://blog.sina.com.cn/s/blog_59ca2c2a0100qhjx.html

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.