2011-12-31 128 views
0

我遇到过两种情况。如何传递Object作为参数与传递Array作为参数不同?

其中一个数组作为参数传递给方法,如果它在被调用方法中更新,它也反映在调用方法中。

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

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

方案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 

如果我在此适用同样的逻辑,字符串对象值的参考(存储器地址)被传递给changeValue,其通过a收到。 因此,现在的a应该指的是与VALUE相同的内存位置。因此,执行a="xyz"时,应该用"xyz"代替​​。

有人可以指出我的理解出错的地方吗?提前致谢!!

回答

0

谢谢大家的答案和更新..

我了解的情况1和2,如下的区别..

在方案1中,数组引用传递。被调用的方法只是更新引用指向的元素之一。

虽然在场景2中传递了引用,但是当被调用的方法将“xyz”赋值给引用变量(指针)时,它实际上会创建一个新的String对象,并将其引用赋值给本地引用变量'a '(指针现在指向一个不同的目标)。

在调用方法的代码是不如

a = new String("xyz"); 

因此,在调用方法的对象和方法调用是绝对不同的,并且indepenedent和具有彼此没有关系。

同样也可以发生在方案1中,如果不是做

b[1] = 9; 

我会用

b = new int[] {8,9,10}; 

我明白,可变性的基本面会来的动作,让我有完成如下...

String a="abc"; 
a="xyz"; 

在这种情况下,对象“abc”被指向由'a'。当'a'被赋予指向新对象“xyz”的职责时,将创建一个新对象“xyz”,该对象不会替换现有对象“abc”。即“abc”仍然存在,但没有参考变量来保持其自身可访问。这种不可替代的财产是因为字符串的不可变性。

2

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

2

这是不一样的东西:

    在第一示例
  • ,传递数组引用作为参数,因此你正确地期望它通过直接操作参考被改变;
  • 但在第二个例子中,你传递了一个对象引用,当然 - 但你改变了引用本身的方法。方法返回时,不会反映对a的更改。

考虑任何对象:

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

一个新的对象被创建,但在调用者也不会改变o。这里也是一样。

+1

不变性是这里的一种红鲱鱼。 – 2011-12-31 16:28:18

+0

是的,在这种情况下,它根本就没有关系。编辑。 – fge 2011-12-31 16:33:10

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 

fooother只引用一个时间同一个对象。一旦foo被分配了一个新的对象,变量不再有任何共同之处。重新分配方法中的参数变量也是如此。

1

你正在做不同的事情;用字符串设置参数值,用数组设置属于的参考。

对于你需要尝试阵列基准设定为一个新的数组等效阵列例如:

public static void changeValue(int[] b) { 
    b = new int[] { 42, 60 }; 
} 

原始数组不会改变。