public class Number()
{
int i;
}public class Test
{
Number n1 = new Number();
Number n2 = new Number(); n1.i = 9;
n2.i = 47; n1 = n2;
n1.i = 27; System.out.println(n2.i);
}n2.i的值应该是27 因为n1这个引用已经被覆盖了,即被仍掉了,而他所指的那个对象(n1.i = 9的那个)被垃圾回收器给清理掉了。(thinking in java中的原话)但是n1 = n2;即被覆盖后,如果那个对象被清理掉后,n1.i = 27 会出错误啊。
难道是等运行完后再清理掉那个对象,请高手帮我讲解下,谢谢

解决方案 »

  1.   

    难到n2.i=27有什么错误吗?"n2.i的值应该是27 因为n1这个引用已经被覆盖了,即被仍掉了,而他所指的那个对象(n1.i = 9的那个)被垃圾回收器给清理掉了。(thinking in java中的原话)"是对的,开始n1,n2分别为不同的对象引用;当n1 = n2后,n1和n2就同时指向同一个对象了,所以n1不会被垃圾回收到.被回收的只是执行n1=n2前,n1所指向的那个对象.根据thinking in java说的,一个对象只有它的引用数量变为0时,java的gc才会将其回收掉.
    "但是n1 = n2;即被覆盖后,如果那个对象被清理掉后,n1.i = 27 会出错误啊。"在执行n1 = n2后,实际上n1和n2指向同一个对象,此时再执行n1.i=27;操作,实际上是和n2.i=27操作的效果是一样的,而不是对原先的n1对象操作.
    ===========================
    呵呵 语文没有学好,上面的文字解释可能不清楚,还是用下面的来解释的.不知道对不对,如果不对,也望高人指点一下:如:执行n1 = n2前的引用关系:
       n1是 Number的一个引用,假设此处的Number对象为C //   (Number n1 = new Number();)
       n2是 Number的一个引用,假设此处的Number对象为D //   (Number n2 = new Number();)执行n1 = n2 后的引用关系:
      n1是对象D的一个引用,此时,由于对象C的引用数量为0,所以被回收掉;
      n2是对象D的另一个应用,
      再执行n1.i=27,实际上是对D对象操作,而不是对原来的C对象操作.
      

  2.   

    谢谢楼上的 ,我已经明白了.
    n2.i的值应该是27 因为n1这个引用已经被覆盖了,即被仍掉了,而他所指的那个对象(n1.i = 9的那个)被垃圾回收器给清理掉了。(thinking in java中的原话)但是n1 = n2;即被覆盖后,如果那个对象被清理掉后,n1.i = 27 会出错误啊。 
    我说的n1.i = 27 会出错应该是编译错误,而其实引用没被仍掉,只是那个对象被清理掉了, 如果象他所说 n1这个引用已经被覆盖了,即被仍掉了 .那用n1.i = 27 肯定编译错误啊(因为n1没了啊),所以我觉得 thinking in java中的原话 让人有点误解,呵呵 不知道我说的有道理不???
      

  3.   

    我来澄清一下n1 = n2;  //这是把句柄n2的值赋给n1   这时n1和n2一样指向的是同一个对象
    //先前n1所指向的对象现在没有句柄跟它关联了  接下来会变成垃圾  但是不一定会被清理
    //因为无法预知垃圾收集器是否工作 以及什么时候工作n1.i = 27;//这是给n1新指向的对象,同时也是n2指向的那个对象的字段赋值  
    //跟n1曾经指向的对象毫无关系所有疑问都是在这两个语句产生的
    如果你对指针或句柄的概念不清楚 就容易迷糊