Java 程序演示按值调用
在编程中,函数通常需要传递给它们参数才能被调用或调用。有两种调用函数的方法,第一种是按引用调用,第二种是按值调用。在本文中,我们将演示 Java 中的按值调用。
按值调用是一种将参数的值作为副本传递给函数的方法,因此在函数内部对此参数所做的任何更改都不会影响超出此函数范围的参数的原始值。
为了帮助详细理解这些概念,我们需要了解用于描述函数参数或参数类型的两个术语。它们是实际参数和形式参数。形式参数是在函数头中定义的,负责接收实际参数。实际参数是在函数调用期间"实际"传递给函数的值或变量。
示例
让我们看一个例子来了解实际参数和形式参数。
public class Main { public static int compute(int p, int q) { // 这两个变量 p 和 q 是形式参数 return p+q; } public static void main(String[] args) { int r=5, s=10; int sum = compute(r, s); //r 和 s 是实际参数 System.out.println("Sum = " + sum); } }
输出
上述程序将产生以下输出 -
Sum = 15
现在记住实际参数和形式参数的概念,重要的是要注意,在按值调用中,实际参数和形式参数是在不同的内存位置创建的,而在按引用调用中,实际参数和形式参数是在相同的内存位置创建的,因此是同步的或实际上是"可修改的"。
示例
这是一个简单的例子来演示 Java 中的按值调用。
public class Main { static void modifyValue(int value) { System.out.println("函数内部变量的值在修改之前为 " + value); value = value + 10; System.out.println("函数内部变量的值在加上 10 之后为 " + value); } public static void main(String[] args) { int a = 5; System.out.println("在调用函数之前,变量 a 的值是 " + a); //调用函数并传递参数 modifyValue(a); System.out.println("在调用函数之后,变量 a 的值是 " + a); } }
输出
上述程序将产生以下输出 -
在调用函数之前,变量 a 的值为 5 在函数内部,变量在未经任何修改之前的值为 5 在函数内部,变量在加 10 之后的值为 15 在调用函数之后,变量 a 的值为 5
在 Java 中,原始数据类型(如 int、float、char 等)通常通过值调用传递给函数,而对象则作为引用传递给方法。为了证明这一点,我们将在下面看另一个例子。在这里,我们将传递 1 个 int(原始数据类型)和 1 个 int 数组(一个对象)。这也将证明按值调用和按引用调用可以在一个函数调用中并行运行。
示例
public class Main { static void modifyValue(int value1, int[] value2) { System.out.println("在函数内部,value1 和 value2[0] 的值在进行任何修改之前分别为 "+value1+" 和 "+value2[0]+""); value1 = value1 + 10; value2[0] = value2[0] + 10; System.out.println("在函数内部,value1 和 value2[0] 的值在向它们添加 10 后分别为 "+value1+" 和 "+value2[0]+""); } public static void main(String[] args) { int a = 5; int[] b = {5}; System.out.println("在调用函数之前,变量 a 和 b[0] 的值为 " + a+" 和 "+b[0]); // 调用函数并将两个参数分别作为 a 和 b 传递 modifyValue(a, b); System.out.println("在调用函数之后,变量 a 和 b[0] 的值为 " + a+" 和 "+b[0]); } }
输出
上述程序将产生以下输出 -
在调用函数之前,变量 a 和 b[0] 的值分别为 5 和 5 在函数内部,value1 和 value2[0] 的值在未进行任何修改之前分别为 5 和 5 在函数内部,value1 和 value2[0] 的值在加上 10 之后分别为 15 和 15 在调用函数之后,变量 a 和 b[0] 的值分别为 5 和 15
在这种情况下,您可以看到"a"的值在函数调用之前和之后保持不变,因为它是通过值传递的。但是,作为对象的整数数组 b 的值在函数调用之后发生了变化,因为它是通过引用传递的。因此,证明了在 Java 中,对象是通过引用传递的,而原始数据类型是通过值传递的。
结论
因此,我们已经看到了按值调用的示例,并了解到它是一种调用函数的技术,其中参数的原始值不会改变。此外,按值调用仅限于原始数据类型,所有对象(如数组)都是通过引用调用传递的。在按值调用中,实际参数和形式参数的内存位置相同。在按值调用中,函数内部所做的所有更改仅保留在函数范围内。值得注意的是,在 1 个函数调用中,可以同时实现按值调用和按引用调用,如上所示,其中 1 个整数和 1 个整数数组(一个对象)作为参数传递给函数。最后,在按值调用中只传递了值的副本。
了解按值调用和按引用调用之间的区别对于编写高效可靠的代码至关重要。然而,总体而言,按值调用更容易理解,也更不容易出错,但在处理大型数据结构时可能会产生意想不到的后果。