抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

前言

本文介绍 Java 的值传递方法。

正文

形参与实参

形参(形式参数)

形参是在函数定义时,函数头中声明的变量。它们是函数用来接收外部数据的占位符变量名

  • 定义时使用:形参只在函数定义时出现,它们不具备实际的值,只是一个约定,告诉函数在调用时会接收哪些类型的数据。
  • 作用域:形参的作用域仅限于函数内部,当函数执行完毕后,形参也就失效了。

实参(实际参数)

实参是在函数调用时,传递给函数的实际值。它们是用来填充形参的真实数据。

  • 调用时使用:实参只在函数调用时出现,它们是具体的数值、变量或表达式。
  • 传递给形参:当函数被调用时,实参的值会被复制(或引用)给对应的形参,然后函数内部就可以使用这些值进行计算。

值传递与引用传递

值传递 (Pass by Value)

值传递是指在调用函数时,实际参数的值被复制一份传递给函数的形式参数。这意味着函数内部对形式参数的任何修改都只作用于这份复制品,而不会影响到函数外部的原始实际参数。可以把这想象成你复印了一份文件给别人,别人在复印件上做了任何改动,原件都不会受到影响。

特点

  • 创建副本: 函数会为每个传入的参数创建一个独立的副本。
  • 独立性: 函数内部对参数的修改与外部的原始数据完全独立。
  • 安全性: 保证了函数不会意外地修改调用者的数据,提高了代码的安全性。

适用场景

  • 当函数不需要修改原始数据时。
  • 传递基本数据类型(如整数、浮点数、布尔值等)。

引用传递 (Pass by Reference)

引用传递是指在调用函数时,实际参数的内存地址(或引用)被传递给函数的形式参数。这意味着形式参数和实际参数指向的是同一块内存空间。因此,函数内部对形式参数的任何修改都会直接影响到函数外部的原始数据。可以把这想象成你把文件的原件直接给了别人,别人在原件上做了任何改动,都会直接体现在原件上。

特点

  • 共享内存: 形式参数和实际参数指向同一内存地址。
  • 相互影响: 函数内部对参数的修改会直接反映到函数外部。
  • 效率: 对于大型数据结构,避免了数据复制的开销,提高了效率。

适用场景

  • 当函数需要修改原始数据时。
  • 传递可变数据类型(如列表、字典、对象实例等)。
  • 在某些语言中,为了避免大型数据结构的复制开销。

Java 的参数传递方式

Java 只有一种参数传递方式——值传递(Pass by Value)

在 Java 中,当你把一个变量传给方法时,传的是这个变量的值的一个拷贝,而不是变量本身。

Java 中传递基本类型

如:int, double, boolean, char, long, float, short, byte.

1
2
3
4
5
6
7
8
9
10
11
public class Test {
public static void changeValue(int num) {
num = 10;
}

public static void main(String[] args) {
int a = 5;
changeValue(a);
System.out.println(a); // 输出 5
}
}
  • a 的值被拷贝一份传给 changeValue 方法
  • 方法里修改的是拷贝,不影响原变量

Java 中传递引用类型

如:数组、类、接口、集合等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Person {
public String name;
}

public class Test {
public static void changeName(Person p) {
p.name = "Tom";
}

public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Jack";
changeName(p1);
System.out.println(p1.name); // 输出 Tom
}
}
  • p1 的引用地址的拷贝被传入方法
  • 方法内通过引用找到对象,修改的是原对象的内容

传递引用类型不能改变引用本身

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {
public static void changeObject(Person p) {
p = new Person(); // 改变的是引用副本
p.name = "Tom";
}

public static void main(String[] args) {
Person p1 = new Person();
p1.name = "Jack";
changeObject(p1);
System.out.println(p1.name); // 输出 Jack
}
}
  • p = new Person() 只改变了副本引用的指向
  • 原来的 p1 没有受影响

后记

Java 中只存在一种参数传递方式,值传递。

评论