java的引用传递和值传递

先来看一段代码的执行结果。

A.java

public class A {
    private String mText;

    public A(String text) {
        mText = text;
    }

    @Override
    public String toString() {
        return mText;
    }
}

Main.java

public class Main {

    public static void main(String[] args) {
        A a1 = new A("a1");
        A a2 = new A("a2");

        System.out.println("a1:" + a1 + " | a2:" + a2);//[1]
        swap(a1, a2);
        System.out.println("a1:" + a1 + " | a2:" + a2);//[3]
    }

    private static void swap(A one, A another) {
        A tmp = one;
        one = another;
        another = tmp;
        System.out.println("one:" + one + " | another:" + another);//[2]
    }
}

位置[1]会打印:a1:a1 | a2:a2
位置[2]会打印:one:a2 | another:a1
位置[3]会打印:a1:a1 | a2:a2


咦?好像有哪里不对,为什么位置[3]会打印a1a2,而不是a2a1呢,在swap()中不是交换过对象了吗?

现在分析一下整个过程:
位置[1]
a1、a2分别指向两个不同的对象,每个对象通过构造函数赋予不同的值来区分,所以在位置[1]打印的结果是显而易见的。”a1:a1 a2:a2”
位置[2]
在swap()中,
1. 因为A是一个类,所以参数是引用传递的,那么one是a1的别名,another是a2的别名。
2. one和another在交换值之后,one指向a2的地址,another指向了a1的地址。
所以,最后打印结果是交换过的。
位置[3]
因为是引用传递,one是a1的别名,another是a2的别名,one和a1、another和a2就是一个东西,在swap中把one和another交换值,就相当于把a1和a2交换了值。
那么最后打印的结果应该是“a1:a2 | a2:a1”

但是实际打印结果和分析的结果是相反。为什么呢?
上述的分析过程是没有错的,那么出问题的地方在哪里?
真相是——第一步就出问题了,整个的分析过程是在参数引用传递这个概念的基础上进行的,前提条件错了,后面的分析结果也必然是有问题的。
事实是,在java中只有值传递,没有引用传递


那么从头再按照值传递的观点分析一下整个过程。
位置[1]
a1、a2分别指向两个不同的对象,a1、a2保存的是两个对象的地址,每个对象通过构造函数赋予不同的值来区分,所以在位置[1]打印的结果是显而易见的。”a1:a1 a2:a2”
位置[2]
在swap()中,
1. 因为A是一个类,参数值传递的是对象的地址,那么one保存的是a1的地址,another保存的是a2的地址。
2. one和another在交换值之后,one保存了a2的地址,another保存了a1的地址。
所以,打印one和another的结果是交换过的。
位置[3]
因为参数是值传递,one和another在参数传递的时候,只是获取了a1、a2保存的值的拷贝,one和another的交换和a1、a2没有任何关系,从而不会导致a1、a2变化,所以再次打印a1、a2的时候,结果仍然是“a1:a1 | a2:a2”


弄清了java的特性,以后遇到对象引用的问题就不会感觉模棱两可了。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值