我有一个关于在Java中更改方法中变量值的问题。
这是我的代码:
public class Test {
public static void funk(int a, int[] b) {
b[0] = b[0] * 2;
a = b[0] + 5;
}
public static void main(String[] args) {
int bird = 10;
int[] tiger = {7};
Test.funk(bird, tiger);
}
}
执行方法Test.funk(bird, tiger)
后,bird的值不会更改 - 它保留值10
,即使在funk()
方法中我们更改了值a = b[0] + 5;
另一方面,数组中元素的值会发生变化,因为我们有语句b[0] = b[0] * 2;
我不明白为什么一件事改变而另一件事没改变?有人可以帮我解释一下。
答案 0 :(得分:18)
请看Jon Skeet关于Parameter-Passing in Java的文章,其中解释了这一点。
简而言之(请查看他的网站以获得更多解释):
数组是引用类型。如果传递指向数组的引用,则复制引用的值并将其分配给函数的参数。因此该参数将指向与传递的参数相同的数组。因此,通过函数参数对数组所做的更改将在调用函数中可见。然而,更改参数本身(b),例如通过将其设置为 null ,调用函数将不会注意到,因为参数(b)只是参数的副本(tiger)过去了。
整数是所谓的原始类型。传递整数会复制其值并将其分配给参数。但该值不是对实际数据的引用,而是数据本身。因此,对函数中参数的更改将影响参数(a),但不会影响调用函数(bird)中传递的参数。
答案 1 :(得分:4)
那是因为当你宣布
时 public static void funk(int a, int[] b)
变量 a 的范围只是该方法。然后,当您更改值时,您只更改 方法中那个变量的值。
关于b。这是对在main中创建的同一个数组的新对象引用,这就是为什么它似乎值确实发生了变化(正在改变的是下面的数组对象)
但试试这个:
public static void funk(int a, int[] b) {
// create a new reference for b
int[] c = new int[b.length];
c[0] = b[0];
b = c;
// The same.
b[0] = b[0] * 2;
a = b[0] + 5;
}
当你这样做时,老虎的价值也没有改变(只有在funk中创建的新数组c的内容)
您可以使用包装器通过ref模拟传递。 See this post.
虽然我对此没有任何意见
编辑只是为了好玩:
我修改了你的代码以使用上面发布的包装器。
它看起来很奇怪,但看起来很有效。
// By ref simulated.
public class Test {
public static void funk(_<Integer> a, int[] b) {
b[0] = b[0] * 2;
a.s( b[0] + 5 ) ;
}
public static void main(String[] args) {
_<Integer> bird = new _<Integer>(10);
int[] tiger = {7};
Test.funk( bird , tiger );
System.out.println("bird = " + bird );
System.out.println("tiger = " + tiger[0] );
}
}
打印
bird = 19
tiger = 14
: - S
答案 2 :(得分:4)
基本上,对象(如数组)通过“引用”传递给方法。因此,当您更改对象时,它会更改传递给方法的同一对象。
Primitives(如int)是“按值传递”,因此您在a中赋值的变量与传入的int变量不同。
我希望这会有所帮助......
答案 3 :(得分:0)
一个变量通过引用传递,另一个变量按值传递:)
What's the difference between passing by reference vs. passing by value?