Java 将对象作为参数传递与将数组作为参数传递有何不同?

Java 将对象作为参数传递与将数组作为参数传递有何不同?,java,object,arguments,Java,Object,Arguments,我遇到了两种情况 一种将数组作为参数传递给方法的方法,如果在被调用的方法中对其进行更新,那么它也会在调用方法中反映出来 但在第二种情况下,字符串对象作为参数传递。对象在被调用的方法中更新,但在调用方法中不反映 我想了解两者之间的区别,即使在这两种情况下,(引用的)值都作为参数传递。请参阅下面的代码片段 情景1: class Test { public static void main(String[] args){ int a[] = {3,4,5}; changeValue(a); Syste

我遇到了两种情况

一种将数组作为参数传递给方法的方法,如果在被调用的方法中对其进行更新,那么它也会在调用方法中反映出来

但在第二种情况下,字符串对象作为参数传递。对象在被调用的方法中更新,但在调用方法中不反映

我想了解两者之间的区别,即使在这两种情况下,(引用的)值都作为参数传递。请参阅下面的代码片段

情景1:

class Test {
public static void main(String[] args){
int a[] = {3,4,5};
changeValue(a);
System.out.println("Value at Index 1 is "+a[1]);
}
public static void changeValue(int b[]){
b[1] = 9;
}
}
输出:

Value at Index 1 is 9
abc
这里,与数组
a
相关的引用(内存地址)被传递到
changeValue
。因此,
b
只是指向与
a
相同的地址。 因此,无论我说的是
b[1]
还是
a[1]
,它都是指相同的内存地址

情景2:

public class Test {
public static void main(String[] args){
String value = "abc";
changeValue(value);
System.out.println(value);
}
public static void changeValue(String a){
a = "xyz";
}
}
输出:

Value at Index 1 is 9
abc
如果我在这里应用相同的逻辑,字符串对象值的引用(内存地址)将被传递给changeValue,它由
a
接收。 因此,现在
a
应该引用与VALUE相同的内存位置。因此,当执行
a=“xyz”
时,它应该用
“xyz”
替换
“abc”


有人能指出我的理解哪里出错了吗?提前谢谢

Java按值传递其所有参数。这意味着将创建一个指向字符串的指针副本,然后将其传递给该方法。然后,该方法使指针指向另一个对象,但原始指针仍然指向同一个字符串。

Java按值传递其所有参数。这意味着将创建一个指向字符串的指针副本,然后将其传递给该方法。然后,该方法使指针指向另一个对象,但原始指针仍指向同一字符串。

这不是同一件事:

  • 在第一个示例中,您将数组引用作为参数传递,因此您正确地期望通过直接操作引用来更改它
  • 但是,在第二个示例中,您确实传递了一个对象引用,但是您在方法中更改了引用本身。当方法返回时,对
    a
    的更改不会反映出来
考虑任何对象:

public void changeObj(Object o)
{
    o = new Whatever();
}

创建了一个新对象,但它不会在调用者中更改
o
。这里也会发生同样的情况。

这不是一回事:

  • 在第一个示例中,您将数组引用作为参数传递,因此您正确地期望通过直接操作引用来更改它
  • 但是,在第二个示例中,您确实传递了一个对象引用,但是您在方法中更改了引用本身。当方法返回时,对
    a
    的更改不会反映出来
考虑任何对象:

public void changeObj(Object o)
{
    o = new Whatever();
}

创建了一个新对象,但它不会在调用者中更改
o
。这里也会发生同样的情况。

这里的区别很简单,实际上并不是关于字符串的不变性,正如一些其他答案(现在已编辑或删除)最初可能暗示的那样。在一个版本(带有字符串)中,您已经重新分配了引用,而在另一个版本(带有数组)中,您没有

 array[0] = foo; // sets an element, no reassignment to variable
 array = new int[] { 1,2,3 }; // assigns new array
 obj = "hey"; // assigns new value
当您重新分配变量时,您不会在方法之外观察到这种变化。当您在不重新分配数组变量的情况下更改数组元素时,您将观察到这些更改。当您在对象上调用setter而不重新指定对象的实际变量时,您将观察到这些更改。当覆盖变量(新数组、分配新值、创建新对象等)时,这些更改将不被注意

参数按值传递(或复制)。方法内部的变量与开始时外部的变量具有相同的值。这些变量没有链接,它们之间也不是别名。它们恰好包含相同的值。一旦您将值重新分配给其中一个,这就不再是真的!外部变量不受内部变量的影响,甚至不受其他局部变量的影响。考虑

Foo foo = new Foo();
Foo other = foo;
foo.setBar(1);
int bar = other.getBar(); // gets 1
foo = new Foo(); 
foo.setBar(42); 
int bar2 = other.getBar(); // still gets 1

foo
other
仅引用同一对象一段时间。一旦
foo
被分配了一个新对象,变量就不再有任何共同点。对方法内参数变量的重新分配也是如此

这里的区别很简单,实际上与字符串的不变性无关,正如一些其他答案(现在已编辑或删除)最初可能暗示的那样。在一个版本(带有字符串)中,您已经重新分配了引用,而在另一个版本(带有数组)中,您没有

 array[0] = foo; // sets an element, no reassignment to variable
 array = new int[] { 1,2,3 }; // assigns new array
 obj = "hey"; // assigns new value
当您重新分配变量时,您不会在方法之外观察到这种变化。当您在不重新分配数组变量的情况下更改数组元素时,您将观察到这些更改。当您在对象上调用setter而不重新指定对象的实际变量时,您将观察到这些更改。当覆盖变量(新数组、分配新值、创建新对象等)时,这些更改将不被注意

参数按值传递(或复制)。方法内部的变量与开始时外部的变量具有相同的值。这些变量没有链接,它们之间也不是别名。它们恰好包含相同的值。一旦您将值重新分配给其中一个,这就不再是真的!外部变量不受内部变量的影响,甚至不受其他局部变量的影响。考虑

Foo foo = new Foo();
Foo other = foo;
foo.setBar(1);
int bar = other.getBar(); // gets 1
foo = new Foo(); 
foo.setBar(42); 
int bar2 = other.getBar(); // still gets 1

foo
other
仅引用同一对象一段时间。一旦
foo
被分配了一个新对象,变量就不再有任何共同点。对方法内参数变量的重新分配也是如此

你在做不同的事情;用你设置的字符串