Java 傳參傳值

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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章