Java引用类型传址 · 为什么传址没改变内容?

辅助代码如下:

class A
{
    int num = 5;
}
class B
{
    public void test(A a){
        a.num = 100;
    }
    public void test2(A a){
        a=new A();
        a.num = 500;
    }
}
public class test {
    public static void main(String[] args) {
        A p = new A();
        System.out.println(p.num);
        
        B b = new B();
        b.test(p);
        System.out.println(p.num);
        
        b.test2(p);
        System.out.println(p.num);
    }
}


运行一下结果是5 100 100

对于第一个答案5应该没有异议;

第二个答案100也好理解,因为引用类型是传址,执行情况如下:

test函数被执行时在栈中push进test这个函数,把参数p传进test函数中后,test中的参数“p”和main中的p指向同一个地址,如图

由于指向的地址一样,所以此时修改p的num也就相当于修改main中p的num。

注意这里修改的是p.num而不是p!!

之后第三个答案,如果按刚才的理解来看的话,为什么不是500?不是说好的传地址能改变吗?

原因在于:test被执行时,是它的参数p指向和main中的p一样的地址,所以修改num的值是同步的。可以这么理解:传参的时候,test中的p接收了来自主函数中的地址,所以test中的p和main中的p指向一致,但是仅仅是指向一致,它并不是主函数中的那个p。

所以,在执行test2的时候,一开始传地址的确是把main中p的地址传过去了,test2中的a一开始的确指向p,但是问题在于test2中又给自己函数体中的参数a创建了一个新对象,那么这个时候a这个参数的指向就变了,不再指向main函数中的p位置,而是指向自己函数中一块新的内存区域并赋值500,对主函数中p.num不会造成任何影响了。同时,test2所创造的空间因为未被使用,在函数执行完会被当作垃圾回收。

所以,最后在执行主函数的输出时,p.num依旧是自己之前的值。

————————————————

一言以蔽之,p=new A()或p=null这样的,直接修改test函数中参数本身指向的就不会改变主函数中的p.num,p.num=500这样,没有改变参数的指向,而是改变参数中其他元素的内容这样,才确保是地址一样,达到修改原来的值的效果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值