什么时候"新"创建新对象,何时复制引用?

时间:2014-06-06 07:02:06

标签: java

我有以下代码,有一个类P如下:

class P {
  char c;

  P (char c){
    this.c = c;
  }
}

然后在程序中有:

P p = new P('a');

void m1 (P p, char z){
  p = new P(z); 
}

m1(p, 'd');

我的问题是在执行方法m1之后,那么我的初始对象p(具有' a')将改变其引用并指向另一个p,其具有任何z保持。或者我会有两个对象p,一个有' a'和另一个z(无论z持有)。如果我有两个对象,为什么会这样?我的意思是我真的很困惑...... m1(p,' d');接受我的p,我在开始时初始化它现在应该指向另一个对象?

2 个答案:

答案 0 :(得分:1)

请记住Java是pass-by-value。因此,您的m1方法会收到p的副本,但它无法更改外部p本身。

void m1 (P p, char z){
  p = new P(z); // this only changes the method argument 'p', not the outer 'p'
}

void someOtherMethod()
  P p = new P('a');
  m1(p, 'z');
  // p has not changed
}

m1方法中,您可以简要地创建一个新的P对象。一旦您的方法完成,该对象就有资格进行垃圾收集,因为没有对它的实时引用。

答案 1 :(得分:0)

Java只是通过价值。

在你的情况下,想象我们有一台电视:

public class Tv {

       boolean on;
       int channel;
       String model;

       Tv (String model) {
           this.model = model;
       }

       public void turnOn(){
           this.on = true;
       }
    }

所以现在我们订购亚马逊的电视 - 耐心等待4-5天。 同时我们为我们的电视购买了一个遥控器。既然有 没有电视控制,我们可以玩我们的遥控器,但 什么都不会发生。在Java中你会说"创建一个参考rcTv,它 是指电视。

   Tv rcTv;  // our Tv remote control

仍然没有电视可以控制。现在门在敲门,Yippee!我们的电视就在那里。 在java中,你说你现在有一个电视实例。

    new Tv(loewe)  // create an instance of an TV-Object

但是如果你无法控制电视的目的是什么(打开/关闭......)! 现在我们必须将遥控器分配给我们的电视。 在java中,你说攻击一个对象的实例

   rcTv = new Tv(loewe); // make rcTv to refer to our Tv-Object

你甚至可以有另一个遥控器

   Tv rcTv2   // new Remote control (reference)

指定(复制)我们之前遥控器的值

   rcTv2 = rcTv;  // make rcTv2 to control the same Tv as rcTv

现在他们两个都指的是同一个电视模型Loewe。 我们编写了一种方法来改变电视的模型。

Tv changeModel (Tv tvarg, String model){
  return tvarg = new Tv(model); 
}

创建第三个遥控器,引用与其他两个相同的电视

Tv rcTv3 = rcTv;    // create another Tv remote-control

现在您可以使用所有三个RC来控制您的Loewe-Tv。 改变最后一个RC的模型。

rcTV3 = changeModel (rcTv, "samsung") 

你可以假设在这次通话之后rcTv将引用一个新的电视实例(三星)。

但如上所述JAVA - >只是通过价值 关键是你给了方法一个参考(对于c / c ++ - Folk一个指针),它可以 指电视对象。

只要JAVA只是通过价值观,你的参考(rcTV)就会被复制 进入方法参数(tvarg)(读取将rcTv克隆到tvarg)。 现在他们两个都会引用相同的电视 - >洛伊

之后
tvarg = new Tv(samsung);

你已经创建了一个新的电视对象,同时你现在强制使用tvarg 引用该Tv对象并将其返回。 所以

之后
rcTV3 = changeModel (rcTv, "samsung") 

你的rcTv仍将引用Tv-Loewe,你的rcTv3将引用电视三星。

问候