3

如果我们将引用变量传递给方法并修改对象的状态,则修改是永久性的(如果我错了,请纠正我)。考虑代码:

 class CardBoard {
    Short story = 200;
    CardBoard go(CardBoard cb) {                        //....(1)
    cb = null;
    return cb;
    }
    public static void main(String[] args) {
    CardBoard c1 = new CardBoard();
    CardBoard c2 = new CardBoard();
    CardBoard c3 = c1.go(c2);       //pass c2 into a method ....(2)
    c1 = null;
    // do Stuff
    } }

在上面的代码中,我们说 cb=null 并返回 cb,c2(以及 c3)现在不应该有 null 引用吗?(PS:原来的问题是在“//do stuff”之后询问符合gc条件的对象。答案是2,但我理解它有问题。)

4

2 回答 2

3

不会,因为cb=null只是将 'cb' 的引用目标从原始实例替换为null,因此c2不会受到影响。

当你只是传入c2函数时,情况会是这样的:

  cb       c2 
  |         | 
------------------
|      object    |
------------------

一旦cb设置为null,它就变成

null--cb       c2 
               | 
  -------------------
  |      object     |
  -------------------

然后你返回 cb 并分配给 c3,它本质上是c3 = null.

但是,另一方面,如果您更改该对象的内部状态,那么所有引用所引用的对象的状态肯定会更改。

于 2013-06-25T19:53:45.737 回答
0

Java 是严格按值传递的

CardBoard go(CardBoard cb) { // here cb has a *copy* of address c2 points to
  cb = null; // when you modify cb, c2 still points to the original location
  return cb; // returning null now
}

CardBoard c3 = c1.go(c2); // c3 becomes null because of explicit assignment
c1 = null; // same as c3

你的大部分困惑来自于观察这个

如果我们将引用变量传递给方法并修改对象的状态,则修改是永久性的。

它显示为按引用传递,但在 Java 中作为(引用的)按值传递

修改仍然存在,因为(地址的)副本仍然指向原始对象。因此,所有触发的方法(使用复制引用)仍然在原始对象上触发。

但是,如果您要销毁这个复制的引用(通过将其设置为null),它不会影响原始对象或指向它的任何其他引用。

于 2013-06-25T19:52:07.763 回答