ava 中参数传递的一个重要特性:Java 总是按值传递参数。这意味着当你将一个变量传递给一个方法时,你实际上是传递了这个变量的副本,而不是它本身。这对于基本数据类型(如 int
, float
, double
, boolean
等)和对象的引用都是成立的。
让我们具体看看这对基本数据类型和对象引用的不同影响:
-
基本数据类型:当你传递一个基本数据类型的变量给一个方法时,Java 会创建这个值的一个副本并传递给方法。这意味着在方法内部对这个变量的任何修改都不会影响到原始变量。方法结束后,修改的是副本,原始变量保持不变。
例如:
void exampleMethod(int num) {
num = 10; // 只修改了副本
}
int originalNum = 5;
exampleMethod(originalNum);
// originalNum 仍然是 5
对象引用:当你传递一个对象的引用给一个方法时,传递的是引用的副本,而不是对象本身。这意味着你不能改变传递进来的引用本身(例如使其指向一个新的对象),但你可以改变这个引用所指向的对象的状态(例如改变对象的属性)。
例如:
void exampleMethod(SomeObject obj) {
obj.setAttribute(10); // 改变了 obj 引用的对象的状态
obj = new SomeObject(); // 这只改变了副本的引用,不影响原引用
}
SomeObject originalObj = new SomeObject();
exampleMethod(originalObj);
// originalObj 的状态已被改变,但它仍然指向同一个对象
因此,在你的情况下,如果你想在递归过程中持续更新一个基本数据类型的值(比如 int
类型的 k
),你不能直接传递 k
,因为在方法中对 k
的任何修改都只会影响它的副本,不会影响原始变量。这就是为什么在递归中使用数组(或其他对象)来存储这样的值是有用的,因为即使传递的是引用的副本,你仍然可以通过这个引用修改共享对象的状态。
针对函数参数不会改变的情况,无论是基本数据类型还是它们的包装类,都是相似的:
-
基本数据类型(如
int
,double
,boolean
等):当你将一个基本数据类型作为参数传递给函数时,传递的是该值的副本。在函数内部对该值的任何修改都仅影响这个副本,不会改变原始变量的值。 -
包装类(如
Integer
,Double
,Boolean
等):尽管它们是对象,但在 Java 中,它们是不可变的。这意味着你不能改变一个现有对象的状态。当你将一个包装类对象作为参数传递给函数时,实际上传递的是对象引用的副本。如果你尝试改变引用的值(即,使其指向一个新的对象),这只会改变副本的引用,而不会影响原始引用。
因此,无论是基本数据类型还是它们的包装类作为参数传递给函数,函数内部对这些参数的任何修改都不会影响原始变量。这一点对于理解 Java 函数参数的行为非常关键。