这可能已经被问到了,但由于我不太确定如何发表意见,我找不到它。
基本上
假设我们有类a,(参见下面的代码),我们想将它的一个实例a1复制到另一个实例a2。
所以,在我的主要内容中我会a1.copy(a2)
我知道使用copy2
方法会有效。但是copy1
不会。我只是想澄清为什么会这样。是因为参数只是对象的“副本”,所以对象本身(a2)不会改变。
class a {
private int val;
public class(int val){
this.val = val;
}
public void copy1(a obj){
obj = this;
}
public void copy2(a obj) {
obj.val = this.val;
}
}
答案 0 :(得分:1)
当您调用 copy1()方法时,该参数是对象 a obj 的引用的副本。当您将其设置为此( obj = this; )时,对象引用的副本将替换为当前对象,但原始对象和对您要调用的位置的对象的引用 copy1()方法保持不变。您只需更改对象引用的副本。
当您调用方法 copy2()时,那里没有完成参考工作,并且您正在逐个匹配变量(对象的属性)并且没有参考副本在那里工作。您正在更改对象本身。在这种情况下, this.val = obj.val; 也可以。
要获得更多理解,请检查this topic并检查其他语言(如C或C ++)如何处理参数传递问题。
答案 1 :(得分:1)
我想你可能想看看如何在Java中传递参数。
对于原始变量,它们按值传递。如果我没记错的话,这意味着传递了一个临时值,并且函数中对变量的任何更改都只更新临时变量。
但是,对象通过引用传递。这意味着代替整个对象,本质上是一个指向对象在内存中的位置的指针。
这意味着更新对象的变量会对该对象产生持久影响。另外,如果您将一个对象设置为等于另一个对象,那么您实际上只是将内存引用设置为相同(这样的副产品就是对象中的变量值然后被链接)。
这解释了为什么第一个功能无法完成您想要的操作(您将内存位置设置为相同)。第二个成功(你正在深层复制到一个新的内存地址)。
答案 2 :(得分:1)
理解您的问题的关键是Java的方法调用始终是按值传递,而不是通过引用。
当您致电a.copy1(b)
时, Java会复制b的参考值(比如说它被称为b_copy,请注意b_copy指向与b相同的内存位置) ,然后将b_copy传递给方法copy1
。
在copy1
的方法中, Java仅更改b_copy的引用。
public void copy1(b_copy){
b_copy=a;
}
现在:
b_copy: b_copy=a;
b: b does not change at all;
当方法结束时,b_copy死亡。所以b上没有任何变化!
虽然a.copy2(b)
操纵对象本身,但它仍会复制b的新值(再次说b_copy)并传入copy2
public void copy2(b_copy){
b_copy.val = a.val;
}
由于b_copy指向b的相同内存,所以当你对b_copy.val进行更改时,你也会在b.val本身上做同样的事情。这就是b改变的原因。
现在:
b_copy: b_copy, but b_copy's val changes
b: b's val also changes, since b_copy is points to the b's memory location;
然后当方法结束时,b_copy死掉,b已经改变了!
上找到更多讨论答案 3 :(得分:0)
你的推理是正确的。将对象传递给方法时(就像在copy1
中那样),您所做的只是创建对同一对象的另一个引用。如果你覆盖这个引用,就像copy1
那样,它只是意味着该引用现在指向另一个对象 - 它不会也不会改变原始对象。