Java方法参数传递

       最近翻车了,之前学习了java参数传递机制以为理解了,但是突然发现还是理解的不太深刻,果然有些问题除非亲身经历否则难以彻底理解。

       之前一般都是利用集合来作为方法的入参,然后再方法内部,操作集合,方法调用之后发现集合也的确发生了自己希望的改变,这一次,也是集合参数作为方法入参,在方法内部将入参重新赋值,以为方法执行完成后,集合会发生改变,没想到却失败了。大致意思如下:

private void test1() {
        // 这里的入参list是栈中临时生成的引用变量  和 外层list同时指向了内存同一块数据
        // 这里赋值只是将这个临时变量指向了Arrays.asList(1) 而外层list并没有改变
        // 方法不能让对象参数引用一个新的对象,方法得到的永远都是拷贝值
        List<Integer> list  = new ArrayList<>();
        System.out.println("before = " + list);
        change(list);
        System.out.println("outer after = " + list);
    }

    private void change(List<Integer> list) {
        list = Arrays.asList(1);
        System.out.println("inner after = " + list);
    }

在外层定义一个空集合,传入到change方法中,在change方法中改变入参,以为方法执行完成list集合会改变,没想到结果如下:方法内部的确改变了 但是外部集合没有改变。

before = []
inner after = [1]
outer after = []

        这是为啥?说到底还是对于java方法入参传参机制不太了解,一句话,java入参传参都是拷贝赋值传递,如果入参是基本类型 则拷贝新的值传递,如果入参是引用 则拷贝引用对象赋值传递。换句话说,方法内部使用的参数list和外部定义的list不是同一个变量,change方法内部参数list是方法执行时在栈中临时生成的,方法执行完成后会自动销毁。

 左边为栈  右边为堆,由下到上执行test1 定义list指向空集合,继而执行change方法,方法入参list此时生成临时变量list(标红),初始时也指向了空集合,后面赋值为集合1 打印输出  方法change结束 list(标红)销毁,注意该过程中list一直指向空  没有变化。

方法不能让对象参数引用一个新的对象,方法得到的永远都是拷贝值

再看下一个

private void test2() {
        // 这里的入参list是栈中临时生成的引用变量  和 外层list同时指向了内存同一块数据
        // 这里list指向的内存区域增加数据  由于外层list指向同一块区域 因此list数据会改变
        // 方法可以改变对象参数的状态,因为方法可以通过对象引用的拷贝修改对象状态
        List<Integer> list  = new ArrayList<>();
        System.out.println("before = " + list);
        change2(list);
        System.out.println("inner after = " + list);
    }

    private void change2(List<Integer> list) {
        list.add(1);
        System.out.println("inner after = " + list);
    }

运行结果如下:

before = []
inner after = [1]
inner after = [1]

可知传入的list对象改变了,这又是为啥,

test2中的list和change2中list指向了内存中同一个内存区域,改变标红list中添加1  此时list也会改变

方法可以改变对象参数的状态,因为方法可以通过对象引用的拷贝修改对象状态

再看下一个

private void test3() {
        int a = 1;
        Integer b = Integer.valueOf(1);
        System.out.println("before a = " + a);
        System.out.println("before b = " + b);
        change3(a, b);
        System.out.println("outer after a = " + a);
        System.out.println("outer after b = " + b);
    }

    private void change3(int a, Integer b) {
        // 这里的 a b都是方法执行时内存栈中生成的临时变量 当方法执行完成后自动销毁
        // 方法不能修改基本数据类型的参数,他们改变的仅仅是他们的拷贝
        a = 2;
        b = Integer.valueOf(2);
        System.out.println("inner after a = " + a);
        System.out.println("inner after b = " + b);
    }

结果如下:

before a = 1
before b = 1
inner after a = 2
inner after b = 2
outer after a = 1
outer after b = 1

 可知对于基本类型  方法内部如何变化都不能改变外部实际参数的值。

方法不能修改基本数据类型的参数,他们改变的仅仅是他们的拷贝

方法入参传递都是值拷贝赋值传递,方法内部参数都是方法执行时栈中临时生成的变量,当如果是基本类型时 则必定不会影响外部实际参数;当如果是引用类型时,栈中临时生成的变量和外部实际参数执行同一个内存区域,如果方法内存改变内存区域 则外部参数执行的内容也会随之改变,如果是重新赋值 则不会改变。

为了便于理解test1 将change方法入参改一下

private void test1() {
        // 这里的入参list是栈中临时生成的引用变量  和 外层list同时指向了内存同一块数据
        // 这里赋值只是将这个临时变量指向了Arrays.asList(1) 而外层list并没有改变
        // 方法不能让对象参数引用一个新的对象,方法得到的永远都是拷贝值
        List<Integer> list  = new ArrayList<>();
        System.out.println("before = " + list);
        change(list);
        System.out.println("outer after = " + list);
    }

    private void change(List<Integer> list2) {
        list2 = Arrays.asList(1);
        System.out.println("inner after = " + list2);
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值