Java基础:值传递机制

先说结论:Java 程序设计语言总是采用按值调用。无论基础数据类型还是引用数据类型。
以下开始证明:

首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。
按值调用 (call by value) 表示方法接收的是调用者提供的值。
按引用调用 ( call by reference)表示方法接收的是调用者提供的变量地址。

先说基本数据类型

基本数据类型

有C基础的人应该不难理解以下这个例子:

	public static void addNum(int num){  //不起作用
        num += 12;
    }
    public static void main(String[] args) {
        int x = 10;
        addNum(10);
        System.out.println(x);
    }

不必理睬这个方法的具体实现, 在方法调用之后, x的值还是 10。
我们来从内存解析角度来看这个问题:
在这里插入图片描述
在C语言中管此叫作用域,num只是拿到了x的值的拷贝,并不能代表x本身。所以对num的操作,都不会对x产生任何影响。
所以基本数据类型Java采用的是值传递机制(也可以叫按值调用)

引用数据类型

我们先看下面这段代码:
这是一段修改员工的工资的代码

	public static void changeSalary(Emp x){
        x.raiseSalary(200);
    }

当调用它时:

	Emp employee = new Emp();
    changeSalary(employee);

这名员工的工资确实提高了200。
看到这里是不是一些读者以为引用数据类型采用的引用传递?
错!
我们来看内存解析:
在这里插入图片描述
我们都知道:
如果变量是基本数据类型,此时赋值的是变量所保存的数据值。
如果是引用数据类型,此时赋值的是变量所保存的数据的地址。

也就是说栈空间中的"employee"和"x"保存的都是Emp的地址,这个过程依旧发生了值传递:employee把值(Emp的地址)拷贝了一份赋值给了x。

到此有点强买强卖的感觉了,因为上一段文字分析虽然解释得通,但是不一定是科学,不一定是真理。必须经过验证才能成为结论!

实践是检验真理的唯一标准

很多程序设计语言(特别是, C++ 和 Pascal) 提供了两种参数传递的方式:值调用和引用调用。有些程序员认为 Java 程序设计语言对对象采用的是引用调用,实际上,这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题。
-----《Java核心技术卷Ⅰ》

我们先写一个交换员工的方法:

	public static void swapEmp(Emp a, Emp b){
        Emp t = a;
        a = b;
        b = t;
    }

我们在main中调用这个方法

        Emp x = new Emp("Jack");
        Emp y = new Emp("Edward");
        swapEmp(x,y);
        //现在x是Edward,y是Jack了吗?

如果Java对引用数据类型采用的按引用调用,那么这个方法应该能实现x和y的交换。但是,方法并没有改变存储在变量 x 和 y 中的对象引用。swap方法的两个参数 a,b被初始化为两个对象引用的拷贝,这个方法交换的是两个拷贝。

初始化时:
在这里插入图片描述

执行swap里面的代码之后:
在这里插入图片描述
最终,白费力气。在方法结束时参数变量 a 和 b 被丢弃了。原来的变量 x 和 y 仍然引用这个方法调用之前所引用的对象。

这个过程说明:Java 程序设计语言对对象采用的不是引用调用,实际上, 对象引用是按值传递的。
下面总结一下 Java 中方法参数的使用情况:

  • 一个方法不能修改一个基本数据类型的参数(即数值型或布尔型)
  • 一个方法可以改变一个对象参数的状态。
  • 一个方法不能让对象参数引用一个新的对象。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值