觀點:Java沒有引用傳遞,隻有值傳遞
基本概念
- 實參:實際參數,是提前準備好并指派完成的變量。配置設定到棧上。如果是基本類型直接配置設定到棧上,如果是引用類型,棧上配置設定引用空間存儲指向堆上配置設定的對象本身的指針。String等基本類型的封裝類型比較特殊,後續讨論。
- 形參:形式參數,方法調用時在棧上配置設定的實參的拷貝。
- 值傳遞:方法調用時,實際參數把它的值傳遞給對應的形式參數,形參接收的是原始值的一個拷貝,此時記憶體中存在兩個相等的變量
- 引用傳遞:方法調用時将實參的位址傳遞給對應的形參,實參和形參指向相同的内容
Java資料有兩個類型
- 基本類型
- 引用類型
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL1cDN3QzM5QzN5YWO3UjNhljNlhzM4kzN2MjM3kjMhZmNjF2YkVmMx8CXt92Yu4GZjlGbh5SZslmZxl3Lc9CX6MHc0RHaiojIsJye.png)
如上圖所示,基本類型傳遞時,線程在棧上配置設定形式參數并拷貝實際參數的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : [email protected] * Description : Test */ public class Test { public static void main(String[] args) { int value = 100; change(value); System.out.println("outer: " + value); } static void change(int value) { value = 200; System.out.println("inner: " + value); } }
結果輸出:
inner: 200 outer: 100
方法修改的隻是形式參數,對實際參數沒有作用。方法調用結束後形式參數随着棧幀回收。
如上圖所示,引用類型傳遞時,傳遞的是引用的值,從這個角度來講還是值傳遞。如果是引用傳遞的話,傳遞的應該是引用的位址,而不是引用的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : [email protected] * Description : Test */ public class Test { public static void main(String[] args) { Person person = new Person(); person.setAge(17); person.setName("Tom"); change(person); System.out.println("outer: " + person.getAge()); } static void change(Person value) { value.setAge(18); System.out.println("inner: " + value.getAge()); } static class Person { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } } }
inner: 18 outer: 18
方法修改的是引用所指向的資料空間的資料,是以方法外部也能看到修改的結果。
基本類型的數組也是對象,是以int[] 傳遞的也是對象應用的值。
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : [email protected] * Description : Test */ public class Test { public static void main(String[] args) { int[] intArray = new int[10]; change(intArray); System.out.println("outer: " + intArray[0]); } static void change(int[] value) { value[0] = 200; System.out.println("inner: " + value[0]); } }
運作結果:
inner: 200 outer: 200
如果對引用類型的傳遞稍作修改
static void change(Person value) { value = new Person(); value.setAge(18); System.out.println("inner: " + value.getAge()); }
inner: 18 outer: 17
用圖解釋為:
同理String,Integer等類型的封裝類型為final類型,對資料的修改操作實際上是建立了一個新的對象
/** * Create with IntelliJ IDEA * Author : wangzhenpeng * Date : 2018/4/8 * Time : 上午9:48 * E-mail : [email protected] * Description : Test */ public class Test { public static void main(String[] args) { String value = "123"; change(value); System.out.println("outer: " + value); } static void change(String value) { value = "abc"; System.out.println("inner: " + value); } }
inner: abc outer: 123