Java的參數傳遞方式java
在編程中,往方法中傳遞參數的方法每每有兩種,一種是值傳遞,一種是引用傳遞,而在java中,全部的參數傳遞所有都是值傳遞。可是實際使用中每每會出現一些相似引用傳遞的方式,下面我將一一舉例說明。編程
首先,java中的全部的對象都是經過「引用」操做的。數組
java中有五個不一樣的地方能夠儲存對象。jvm
1)寄存器:這是最快的儲存區域,可是這個區域並不能由用戶直接控制,用戶也感受不到寄存器的存在。函數
2)堆棧:位於通用RAM中,經過堆棧指針能夠得到直接支持。Java的對象引用及儲存在堆棧之中,可是java對象並不儲存在堆棧中。測試
3)堆:一種通用的內存池,也存在於RAM中,用於存放全部的java對象,經過new關鍵字建立的對象都會存在於堆中。spa
4)常量儲存:常量值一般直接存在於程序代碼內部,並存放在ROM(只讀存儲器)中。指針
5)非RAM儲存:存活於程序以外的數據。code
1.傳遞基本類型數據。對象
java中的基本類型數據即 int,char這一類。測試代碼以下:
1 package com.csust.wk; 2 public class FunctionTest1 { 3 public static void change(int b){ 4 b = 10; 5 } 6 7 public static void main(String[] args) { 8 int i = 5; 9 System.out.println(i); 10 change(i); 11 System.out.println(i); 12 } 13 }
程序輸出:
5
5
由結果可見,傳入change()方法中的變量並無被改變。
結果分析:
在基本類型int建立的過程當中,如int a = 5; java首先會在堆棧中(全部基本類型的建立和保存都是在堆棧中進行的操做)查詢有沒有5這個值,若是沒有則會在堆棧中開闢一個新的內存空間同時將5置入該空間。而後a這個引用就指向了5所在的內存空間。
這麼看的話,將a傳入change()方法之中後,形參b指向了main函數中的實參a的地址(此處也是值傳遞,由於java 複製了一份實參a 的地址而後將其賦給b),對b進行b=10的操做時,java則按照以上的規則進行操做,因爲a,b並非同一個引用,因此當b的引用地址改變成10之後,a所指向的依舊是5所在的地址,這樣就能夠獲得以上的輸出結果了。另附基礎對象
public static void main(String[] args) { /* * 基礎對象測試代碼2 */ int a = 5; int b = a; b = 10; System.out.println(a); System.out.println(b); }
2.數組數據傳遞
測試代碼:
package com.csust.wk; public class FunctionTest1 { public static void change(int[] arg){ arg[0] = 10; } public static void main(String[] args) { int[] arg = {1,2,3,4,5,6}; System.out.println(arg[0]); change(arg); System.out.println(arg[0]); } }
程序輸出:
1
10
結果可見:傳入的arg數組中的值被改變了,arg[0]由1變成了10。
結果分析:
數組實際上結構是保存了一系列的引用,arg[0]是一個指向數組中第一個int儲存空間的引用。而arg則是指向了該數組的引用。
當arg被傳入change()方法時,複製了一個arg的引用,可是該arg也是隻想實參arg的地址的,因此對arg[0]進行操做時實際上也是對元數組進行了賦值操做,當回到main函數時,調用的依舊是change()中操做的地址,因此第二次輸出會變成 10 。
3.對象傳遞
測試代碼:
package com.csust.wk; class TestClass { int a; } public class FunctionTest1 { public static void change(TestClass c){ c.a = 10; } public static void main(String[] args) { TestClass cla = new TestClass(); cla.a = 5; System.out.println(cla.a); change(cla); System.out.println(cla.a); } }
結果:
5
10
結果分析:cla中的a變量被改變,結果輸出爲10。
類是保存在由jvm分配內存保存在堆中的,當類的引用被傳遞到方法中後,該方法中對該類內的操做都是經過堆內存來操做的,因此會生效。
不會生效的是以下方式:
package com.csust.wk; class TestClass { int a; } public class FunctionTest1 { public static void change(TestClass c){ /*不會生效的方式*/ c = new TestClass(); c.a = 10; } public static void main(String[] args) { TestClass cla = new TestClass(); cla.a = 5; System.out.println(cla.a); change(cla); System.out.println(cla.a); } }
因爲值傳遞傳遞的是引用的複製,當將方法中的c引用從新定位到新的類(即不一樣的內存地址)的時候,對新的類的操做是不會影響到原類的,也就是說,java的值傳遞的意思是,傳遞的過程當中能夠對原引用形成必定的影響,能夠改變引用對象中的數據,可是不能夠直接操做到該引用,由於java傳遞過去的不是一個指向源引用的指針,而是原引用的一個複製,這個值傳遞的概念是成立的,只是因爲java對於值傳遞的特殊處理方式因此致使有的人對該值傳遞產生必定的質疑。