【Java小知识】按值传递还是引用传递?

前言

之前一直有疑惑,Java到底是按值传递还是按引用传递,大家都知道基本数据类型是按值进行传递,那么对象是怎么传递的呢?

概念

我们先下简单过一下,这两个概念:

按值调用(call by value):表示方法接收的是调用者提供的
按引用调用(call by reference):表示方法接收的是调用者提供的变量地址

按值调用,也就是说方法得到的所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量内容。

基本数据类型

我们都知道基本数据类型是按值传递,下面写一个简单的demo:changeValue()方法试图改变一个参数的值:

    public static void changeValue(double x) {   //doesn’t work
        x = 2 * x;
        System.out.println("x==" + x);
    }
    public static void main(String[] args) {
        double number = 10;
        changeValue(number);
        System.out.println("number==" + number);
    }

结果如下:number的值仍然为10,并没有改变。

x==20.0
number==10.0

具体的执行流程如下,如下图所示,对值参数的修改没有保留下来:

  1. x被初始化为number值的一个拷贝(也就是10);
  2. x被乘于2后等于20,但是number仍然是10;
  3. 这个方法结束后,参数变量x不再使用。
    在这里插入图片描述

对象引用

上面讲了基本数据类型的参数不能被改变,而对象引用作为参数就不同了,可以很容易实现对参数的改变,如下所示:

    public static void main(String[] args) {
        Basic basic = new Basic(1, "hello");
        Basic basic1 = change(basic);
        System.out.println(basic.toString());
    }
    static Basic change(Basic x) {  //work
        x.setA(2);
        x.setS("world");
        System.out.println(x.toString());
        return x;
    }

结果:我们可以看到Basic对象的值变了。

2====world
2====world

具体的执行流程如下,如下图所示,对对象参数的修改保留了下来:

  1. x被初始化为basic值的拷贝,这里是一个对象的引用;
  2. change方法应用于这个对象引用。x和basic同时引用的那个Basic对象的内容改变成了(2,world);
  3. 方法结束后,参数变量x不再使用。当然,变量basic继续引用那个修改后的(2,world)对象。
    在这里插入图片描述

why?

方法得到的是对象引用的拷贝,对象引用及其他的拷贝同时引用了同一个对象。那么我们可以认为Java对象采用的是引用调用了吗??别急,继续看下,我们写一个交换x,y的swap方法,如果是引用调用,那么理论上应该baisc和basic1的值交换的效果。

    public static void main(String[] args) {
        Basic basic = new Basic(1, "hello");
        Basic basic1 = new Basic(2,"world");
        swap(basic,basic1);
        System.out.println(basic);
        System.out.println(basic1);
    }

    static void swap(Basic x, Basic y) {
        Basic temp = x;
        x = y;
        y = temp;
    }

结果是什么?what?竟然值没有发生改变…,因为方法并没有改变存储在变量basic和basic1中的对象引用。swap方法的参数x和y被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝。最终,白费力气,在方法结束时参数变量x和y被丢弃了。原来的变量basic和basic1仍然引用了这个方法调用之前所引用的对象。

实际上,对象引用是按值传递的,不过"值"是对应的引用。

1====hello
2====world

小结

不管是基本数据类型还是对象引用其实都是值传递,传递是值的拷贝,基本数据类型是其本身值的拷贝,对象的引用的拷贝,拷贝的引用并不会改变原引用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值