Java值传递

形式参数和实际参数

  • 实际参数/实参:用来传递给函数/方法的参数,必须要有确定的值,其实可以认为是方法外部的参数就是实际参数
  • 形式参数/形参:用来定义函数/方法,接受实参,不需要有确定的值,方法内部定义的或者在方法定义时需要传入的参数就是形参
// 实际参数
String hello = "Hello";
sayHello(hello);
//str是形式参数
void sayHello(String str) {
  System.out.println(str);
}

值传递 和 引用传递

编程语言将实际参数传递给方法/函数的方法有两种:

  • 值传递:方法接受的是实际参数的值的拷贝,会创建副本
  • 引用传递:方法接受的是实际参数的地址,而不是实际参数的值这就是指针,此时实际参数就是形式参数,对形式参数的任何修改都会反应到实际参数,包括重新赋值

Java中只存在值传递


为什么在Java中只存在值传递

直接看例子

传递基本数据类型参数

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);
}
//a和b是形式参数
public static void sawp(int a, int b){
  int temp = a;
  a = b;
  b = temp;
  System.out.println("a = " + a);
  System.out.println("b = " + b);
}

输出

a = 20
b = 10
num1 = 10
num2 = 20

swap()中进行ab的交换,不会对num1num2带来影响,因为传给ab的值都是通过对num1num2复制得到的,是将其副本赋值给形式参数,不管副本怎么修改都不会对元件到来影响


传递引用数据类型参数

public static void main(String[] args){
  // 实际参数
  int[] arr = {1, 2, 3, 4, 5};
  System.out.println(arr[0]);
  change(arr);
  System.out.println(arr[0]);
}
// array是形式参数
public static void change(int[] array){
  array[0] = 0;
}

输出

1
0

注意,这里还是值传递,只不过这个值是实际参数的地址,所以有些人会觉得这个是引用传递,实则不然

所以方法change的参数拷贝的是arr实际参数的内存地址,于是形式参数array也指向这个内存地址,所以指向同一个堆空间的值,所以无论是实际参数发生修改还是形式参数发生修改都会对值带来影响

public class Person {
  private String name;
}
public static void main(String[] args){
  //这两个是引用数据类型的实际参数
  Person xiaoZhang = new Person("小张");
  Person xiaoLi = new Person("小李");
  swap(xiaoZhang, xiaoLi);
  System.out.println("xiaoZhang:" + xiaoZhang.getName());
  System.out.println("xiaoLi:" + xiaoLi.getName());
}
//person1和person2是形式参数
public static void swap(Person person1, Person person2) {
    Person temp = person1;
    person1 = person2;
    person2 = temp;
    System.out.println("person1:" + person1.getName());
    System.out.println("person2:" + person2.getName());
}

输出

person1:小李
person2:小张
xiaoZhang:小张
xiaoLi:小李

因为本质是值传递,只不过这个值传递传递的是实际参数的内存地址,即把实际参数的内存地址传递给形式参数,那么形式参数之间进行修改交换,不会对实际参数的内存地址造成改变,所以只要实际参数指向的值不修改,那么实际参数就不会发生改变


引用传递

那么通过上面的三个例子,我们已经知道了Java只有值传递,没有引用传递,但是C++是有引用传递的,那么接下来就看看引用传递

#include <iostream>
//num是形式参数
void incr(int& num)
{
  std::cout << "incr before:" << num << "\n";
  num++;
  std::cout << "incr after:" << num << "\n";
}
int main()
{
  // 实际参数
  int age = 10;
  std::cout << "invoke before:" << age << "\n";
  incr(age);
  std::cout << "invoke after:" << age << "\n";
}

输出

invoke beforer:10
incr brfore:10
incr after:11
invoke after:11

在方法内部对形式参数的值进行修改是会对实际参数的值带来影响的,而且注意一下int&才是引用传递,如果是int就是值传递


Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐