我遇到过两种情况。
一个数组作为参数传递给方法,如果在被调用的方法中更新,它也会在调用方法中反映出来。
但在第二种情况下,String对象作为参数传递。该对象在被调用的方法中更新,但它不会反映在调用方法中。
我想了解两者之间的区别是什么,即使在这两种情况下,value(of reference)都作为参数传递。请参阅下面的摘录。
情景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
此处,与数组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";
}
}
输出:
abc
如果我在此处应用相同的逻辑,则String Object VALUE的引用(Memory Address)将传递给changeValue,由a
接收。
因此,现在a
应该引用与VALUE相同的内存位置。因此,执行a="xyz"
时,应将"abc"
替换为"xyz"
。
有人可以指出我的理解出错了吗?在此先感谢!!
答案 0 :(得分:2)
Java按值传递所有参数。这意味着生成指向String的指针的副本,然后传递给该方法。然后该方法使指针指向另一个对象,但原始指针仍然指向相同的String。
答案 1 :(得分:2)
这不是一回事:
a
的更改不会反映出来。
考虑任何对象:
public void changeObj(Object o)
{
o = new Whatever();
}
创建了一个新对象,但它不会在调用者中更改o
。这里也是如此。
答案 2 :(得分:1)
这里的区别很简单,实际上它并不是关于字符串的不变性,因为其他一些答案(现在已编辑或删除)可能最初暗示。在一个版本中(使用字符串),您已经重新分配了引用,而在其他版本中(使用数组),您还没有。
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
分配新对象后,变量不再具有任何共同点。对于方法中的参数变量的重新分配也是如此。
答案 3 :(得分:1)
对于等效数组示例,您需要尝试将数组引用设置为新数组:
public static void changeValue(int[] b) {
b = new int[] { 42, 60 };
}
原始数组不会被更改。
答案 4 :(得分:0)
谢谢大家的答案和更新..
我理解方案1和2之间的区别如下..
在方案1中,传递数组引用。被调用的方法只更新引用指向的元素之一。
在方案2中,引用被传递,但是当被调用的方法将“xyz”赋给引用变量(指针)时,它实际上创建了一个新的String对象,并且它的引用被分配给本地引用变量'a' (指针现在指向一个不同的对象)。
被调用方法中的代码与
一样好a = new String("xyz");
因此,被调用方法和调用方法中的对象是完全不同且独立的,并且彼此没有关系。
情节1也可能发生同样的情况,如果不是做
b[1] = 9;
我会用
b = new int[] {8,9,10};
我明白,如果我可能会像下面这样做,可变性基本原理就会起作用。
String a="abc";
a="xyz";
在这种情况下,对象“abc”被“a”指向。当'a'被赋予指向新对象“xyz”的职责时,创建新对象“xyz”,其不替换现有对象“abc”。即“abc”仍然存在但没有参考变量以保持自身可访问。这种非替换属性是由于字符串的不变性。