详解Java中的值传递

143 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第17天,点击查看活动详情

前面所需的概念

首先我们来讲解传递这个概念,分为俩种

  • 形参
  • 实参
  • 值传递
  • 引用传递

形参&实参

方法的定义中可能会用到参数(有参的方法),参数在编程语言中又分为实参和形参,

形参:形式参数,指代方法中接收实际参数的参数,不需要有确定的参数

实参:实际参数,指代传递给方法的参数,必须要有确定的参数

在代码中确切的看为:

String qwq = "QWQ";
//qwq为实际参数
//str 为形式参数
void helloworld(String str){
    System.out.println(str);
}

值传递和引用传递

如果大家学过c++,那这块肯定是明白的,但是Java中没有引用传递,在编程语言中,将实参传递给方法的方式有俩种就是我们即将要说的,

  • 值传递:方法接收的是实参值的拷贝,会创建副本。
  • 引用传递:方法接收的是实参所引用对象在堆中的地址,不会创建副本,对形参的修改将影响到实参

为什么Java中只有值传递

至于这个问题,有的小伙伴可能不相信,那我们用例子来说明

  1. 传递基本参数
package 随便;

public class 参数传递 {

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;
        swap(num1,num2);
        System.out.println("num1:"+num1);
        System.out.println("num2:"+num2);

    }
    public static void swap(int a, int b){
        int temp = a;
        a = b;
        b = temp;
        System.out.println("a:"+a);
        System.out.println("b:"+b);
    }
}

输出结果: 请添加图片描述

原因: 请添加图片描述

swap() 方法中,ab 的值进行交换,并不会影响到 num1num2。因为,ab 的值,只是从 num1num2 的复制过来的。也就是说,a、b 相当于 num1num2 的副本,副本的内容无论怎么修改,都不会影响到原件本身。

那么我们如何实现,交换俩个基本数据类型的参数呢?在c++中我们会使用指针或者引用来交换地址,而在Java中,提供了对象引用作为参数

  1. 对象引用作为参数
public class 参数传递 {
    public static void swap(int[] arr){
        int temp=arr[0];
        arr[0]=arr[1];
        arr[1]=temp;
    }
    public static void main(String[] args) {
        int[] nums=new int[2];
        nums[0]=10;
        nums[1]=20;
        swap(nums);
        System.out.println(nums[0]+" "+nums[1]);
    }
}

输出结果: 请添加图片描述

请添加图片描述

这里传递的还是值,不过,这个值是实参的地址罢了!

也就是说 change 方法的参数拷贝的是 arr (实参)的地址,因此,它和 arr 指向的是同一个数组对象。这也就说明了为什么方法内部对形参的修改会影响到实参。

总结

如果参数是基本类型,传递的是基本类型的字面量值的拷贝。

如果参数是引用类型,传递的是该参量所引用的对象在堆中地址值的拷贝。

知乎高赞:Java到底是值传递还是引用传递