创建了类的新实例或仅分配了内存空间?

时间:2016-07-16 20:39:47

标签: java instance

更新

public Fish mate(Fish other){
  if (this.health > 0 && other.health > 0 && this.closeEnough(other)){

    int babySize = (((this.size + other.size) /2));
    int babyHealth = (((this.health + other.health) /2));
    double babyX = (((this.x + other.x) /2.0));
    double babyY = (((this.y + other.y) /2.0));

    new Fish (babySize, babyHealth, babyX, babyY);
  }
  return null;
}

调用new Fish时,是否有Fish的新实例在没有引用的地方浮动,或者我刚刚为新Fish分配了内存没有实际实例化它?

我是否可以通过new Fish调用来创建Fish的实际实例,其具有唯一的引用名称而非迭代循环?

4 个答案:

答案 0 :(得分:8)

  

当调用新的Fish时,是否有一个新的Fish实例在没有变量名的地方浮动,或者我刚刚为新的Fish分配了内存而没有实际实例化它?

将创建一个新的Fish对象,并且由于没有对它的引用而将被垃圾收集。 Fish的构造函数完成后,垃圾收集将在(某个时间)进行。
在你的情况下没有多大意义,但有时它确实如此,如果实例化一个对象将启动一个新的Thread或运行一些你想要只运行的其他例程

  

如果我只分配了内存或者Fish没有名称,我怎样才能获得新的Fish调用以使用唯一变量创建Fish的实际实例命名

这不是很清楚。但是我觉得你只想return new Fish(...);并将它自己分配给变量,你可以在其中调用它,例如:

Fish babyFish = femaleFish.mate(maleFish);

答案 1 :(得分:4)

  

我刚刚为新Fish分配了内存而没有实际实例化它?

没有。该实例已初始化(构造函数已执行),但如果没有为此实例保留引用,则最终将进行垃圾回收。请记住,即使您的代码没有这样做,也可以保留引用,例如,如果构造函数将this置于某个静态变量中。

答案 2 :(得分:3)

下图的解释在我开始时遇到困惑时确实对我有所帮助,我希望也能帮到你。你可以把员工视为鱼。

enter image description here

在您的情况下,您在方法内部本地创建了一个new Fish()对象,因此其生命周期也应该在本地分配。垃圾收集器始终查找未使用的对象,并且会尽快识别出适合收集的对象。您的方法以及方法内定义的其他局部符号退出。

您返回null,因此不能将此方法视为工厂方法结构,因为它不返回实例。我不确定您的意思:

  

我是否可以使用新的Fish调用创建一个具有唯一引用名称的Fish的实际实例,而不是迭代循环?

但我想你问你是否可以使用方法中的确切new Fish()。简短的回答是:不。虽然你绝对可以创建另一个new Fish()但你需要一个引用变量来检索该地址,或者你可以返回该方法的实例而不是null,这将是一个静态工厂方法,并且当你的时候被称为一个好习惯想要单独命名你的构造函数。

以更具体的方式回答您更新的两个问题:

1)你在编写new Fish()时创建了一个新对象,但是你没有创建一个引用变量来真正检索那个对象信息。就像你已经建了一个房子但你不知道地址那房子。然后你永远不能到达房子。会发生什么是因为缺少检索过程,这个对象将被垃圾收集器识别为未使用,因此将被收集。

2)由于没有引用/指针或任何东西来获取存储在新对象中的信息,因此您无法在方法中检索确切的new Fish(),但如果您使用引用变量,您当然可以创建另一个对象真的希望检索存储在对象中的信息。

最后,尽管它主要是为C语言使用而编写的,但斯坦福大学的Nick Parlante撰写的以下文档在解释引用,堆栈和堆内存方面做得非常出色。Click here.

答案 3 :(得分:2)

首先,让我澄清你的术语中的一些混淆:对象没有名字。 变量有一个名称,但是您可以将许多不同名称的变量都引用到同一个对象。具有命名变量引用该对象并不意味着该对象具有名称。

如果您执行new Fish()但未将新引用分配给任何内容,则构造函数返回后,新对象将无法访问

无法恢复该引用,并且该对象将在下一次垃圾收集运行时取消分配。