Java 值傳遞和引用傳遞
阿新 • • 發佈:2020-07-23
目錄
結論
java中都是值傳遞,沒有引用傳遞。
如果引數型別是原始型別,那麼傳過來的就是這個引數的一個副本,也就是這個原始引數的值,這個跟之前所談的傳值是一樣的。如果在函式中改變了副本的值不會改變原始的值.。
如果引數型別是引用型別,那麼傳過來的就是這個引用引數的副本,這個副本存放的是引數的地址。如果在函式中沒有改變這個副本的地址,而是改變了地址中的值,那麼在函式內的改變會影響到傳入的引數。如果在函式中改變了副本的地址,如new一個,那麼副本就指向了一個新的地址,此時傳入的引數還是指向原來的地址,所以不會改變引數的值。
經典題目
class Person { int age = 10; } public class Main { public static void main(String[] args) { //case 1 int var1 = 10; change(var1); System.out.println(var1); //case 2 Person var2 = new Person(); change(var2); System.out.println(var2.age); //case 3 String var3 = "hello"; change(var3); System.out.println(var3); //case 4 Person var4 = new Person(); changeNew(var4); System.out.println(var4.age); } private static void changeNew(Person var4) { var4.age = 20; var4 = new Person();//這裡更改了入參的地址 var4.age = 10; } private static void change(String var3) { var3 = "world"; } private static void change(Person person) { person.age = 20; } private static void change(int var1) { var1 = 20; } }
在case 1中,入參是基本資料型別,所以修改的是副本的數值,不會影響原變數。
在case 2中,入參是引用物件,傳入的是引用變數的地址,所以修改了地址所對應的值,會影響原變數。這裡引用變數也包括陣列,對於陣列來說傳入的是第一個元素的地址。
在case 3中,入參是String,是一個引用型別,但是String是一個final類,所以傳入的是地址,對String的改變是重新開闢新的空間,而不是修改地址對應的內容,所以也不會修改原變數的值。
在case 4中,原理和case 3類似,也是開闢了新的地址空間,所以並沒有對原地址所對應的內容進行改動。
輸出為
10
20
hello
20