首先,我了解Java中所谓的passing by value
。
我也理解,当你传递一个对象或数组时,它是传递给方法的数组地址。因此修改方法内的数组变量会影响外部数组变量。
例如,
private void change(int[] a) {
a[0] = 1234;
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
输出为1234
,因为a
内的change
实际上是外面的数组。
我不明白的是以下代码:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
public static void main(String[] args) {
int[] a = new int[2]{1,2};
change(a);
System.out.println(a[0]);
}
为什么输出为1
,而不是1234
?
内部a
与外部a
相同,对吧?我也修改了内部a
,就像上面的例子一样,为什么有两个不同的输出?
答案 0 :(得分:3)
这不一样。在第二个示例中,您将更改本地引用a
以引用一个全新的数组,而不是更改现有数组。但是这不会改变main中的a
来引用新数组;它仍然引用旧数组,因此打印1
。
如果您想使用方法将全新数组重新分配给a
中的main
,请从change
返回新数组并将其分配给a
} main
。
答案 1 :(得分:1)
让我们检查你的功能:
private void change(int[] a) {
a = new int[3]{1234, 4, 5};
}
正如您在问题中所述,a
是对数组的引用。如果您使用它来修改数组(例如,a[0]=1234
),您将更改传入函数的相同数组。
但是,如果您更改引用本身,则a将不再指向原始数组,对其进行更改不会影响原始数组。
答案 2 :(得分:0)
这正是因为引用是按值传递的。我们将使用像12345
这样的5位数字来表示对象指针。过程如下:
int[]{1,2}
,例如10000
。我们为a
分配值10000
。 a
位于与main
对应的堆栈框架上。change
。change
执行:
change
在位置20000处创建一个新数组,并将其堆栈帧上的a
值设置为20000.这样做不影响main
堆栈框架。change
返回(无效)。1
。请注意,在change
返回时,我们没有留下{1234, 4, 5}
的实时参考。
答案 3 :(得分:0)
在Java中,所有变量都是对象的引用。
将变量传递给数组时,将引用传递给对象。如果您修改了对象,那么调用方法(也有一个引用同一对象的变量)会看到更改。
当您编写“a = new int ...”时,您正在将变量a的值更改为指向其他对象。它不再引用与调用它的方法中的对象相同的对象。所以调用方法和被调用方法看到了不同的东西。
答案 4 :(得分:0)
当您按值传递参数时,它基本上意味着从方法的角度复制它。因此,您对数组有一个引用a
,当您将它传递给某个方法时,在该方法中,您有另一个引用,也称为a
到同一个数组。现在,当您为该引用(a = new int[]...
)分配新值时,您只需修改本地a
变量以指向新数组。
答案 5 :(得分:0)
当您尝试进行更改时,答案与通过引用或值传递一样多,因为它与哪些变量在范围内有关。
当您将“a”或任何变量传递给方法时,您传递该变量的值 - 换句话说,传递它所代表的内容的副本 - 而不是实际变量本身。例如:
public static void main(String[] args){
int a = 3;
addTwo(a);
System.out.println(a);
}
private void addTwo(int a){
a += 2;
}
在上面的示例中,值3传递给addTwo。 main方法中的变量“a”超出了其范围(即它本地化为main方法),因此addTwo方法仅对“a”,值3的副本起作用,而不是对变量起作用。变量“a”保持不变。当方法完成时,丢弃a的值并且main方法中的原始“a”保持不变。
这与您的情况相同。对两个变量使用相同的名称并不重要。主方法中的变量不会更改。