Java 傳參傳值
案例代碼
public class PassParamExplain {
public static void main(String[] args) {
//example A
System.out.println("example A:");
Integer a = 2018;
passInteger(a);
System.out.println(a);
a = passInteger(a);
System.out.println(a);
//example B
System.out.println("example B:");
Pojo pojo1 = new Pojo(2021, "2021");
passPojo(pojo1);
System.out.println("pojo1 x:" + pojo1.getX() + " y:" + pojo1.getY());
//example C
System.out.println("example C:");
Pojo pojo2 = new Pojo(2022, "2022");
pojo2 = passPojo(pojo2);
System.out.println("pojo2 x:" + pojo2.getX() + " y:" + pojo2.getY());
//example D
System.out.println("example D:");
Pojo pojo3 = new Pojo(2023, "2024");
passPojoAndReassign(pojo3);
System.out.println("a: pojo3 x:" + pojo3.getX() + " y:" + pojo3.getY());
pojo3 = passPojoAndReassign(pojo3);
System.out.println("b: pojo3 x:" + pojo3.getX() + " y:" + pojo3.getY());
}
public static Integer passInteger(Integer arg) {
arg = 2019;
return arg;
}
public static Pojo passPojo(Pojo pojoA) {
pojoA.setX(2019);
pojoA.setY("2019");
return pojoA;
}
public static Pojo passPojoAndReassign(Pojo pojoB) {
pojoB = new Pojo(2020, "2020");
return pojoB;
}
}
public class Pojo {
private Integer x;
private String y;
public Pojo(Integer x, String y) {
this.x = x;
this.y = y;
}
public Integer getX() {
return x;
}
public void setX(Integer x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
}
案例分析
- example A
- 調用passInteger(a)時,産生了一個新的局部變量arg,并且變量arg被指派為a存放的引用,緊接着執行方法passInteger内的指派語句 arg = 2019,此時局部變量arg被重新指派為一個新的引用;
- 隻執行passInteger(a)并不會修改main方法變量a的值(即變量a存放的引用),因為passInteger方法隻對局部變量arg重新指派并傳回,調用passInteger(a)方法時僅僅是把變量a存放的引用傳給了變量arg
- 執行 a = passInteger(a)時; 因為passInteger方法傳回了一個新的引用(且每次調用都傳回一個新引用,因為 arg = 2019 語句産生了新的對象), 并且指派給了變量a,是以main方法變量a當然是改變了
- example B
- 調用passPojo(pojo1)時,産生了一個新的局部變量pojoA,并且變量pojoA被指派為參數pojo1的值(即pojo1存放的引用),此時變量pojoA的值為變量pojo1存放的引用(該引用指向pojo1對象的記憶體空間),兩個變量存放的引用是相同的;
- 執行pojoA.setX(2019); pojoA.setY("2019"); 修改了該引用指向的記憶體空間的資料,是以即使僅僅調用passPojo(pojo1),變量pojo1指向的記憶體空間的資料也會相應得到改變
- example C
- pojo2 = passPojo(pojo2);與passPojo(pojo2);的差別是前者接收了方法passPojo傳回的引用,并指派給了變量pojo2;但根據example B的分析可得,調用passPojo(pojo2)傳回的引用其實和調用之前pojo2存放的引用是指向同一個空間的引用,
- 隻是變量pojoA存放的是變量pojo2指向的記憶體空間引用的副本而已;
- example D
- example D和example A本質其實是相同的,
- passPojoAndReassign(pojo3)時,産生了一個新的局部變量pojoB,并且變量pojoB被指派為pojo3存放的引用,緊接着執行方法内語句pojoB = new Pojo(2020, "2020"); 此時局部變量pojoB被重新指派為一個新的引用,該新引用指向new Pojo(2020, "2020")對象存放的記憶體空間;隻修改了變量pojoB存放的引用,變量pojo3沒有任何修改;
- 隻執行passPojoAndReassign(pojo3),由于變量pojo3沒有接收passPojoAndReassign方法的傳回值是以并不會修改main方法變量pojo3存放的引用,而且passPojoAndReassign方法内也沒有修改變量pojo3存放的引用指向的記憶體空間的資料,是以變量pojo3沒有任何改變;
- pojo3 = passPojoAndReassign(pojo3);與passPojoAndReassign(pojo3)的唯一的不同點是前者用變量pojo3接收了passPojoAndReassign方法傳回的新的引用,且每次調用passPojoAndReassign方法都傳回一個新引用,是以main方法中變量pojo3存放的引用被改變了
案例資料變化列印輸出
example A:
2018
2019
example B:
pojo1 x:2019 y:2019
example C:
pojo2 x:2019 y:2019
example D:
a: pojo3 x:2023 y:2024
b: pojo3 x:2020 y:2020