2017-03-06 71 views
0

在此循环中有一个名为pawn的变量,但该循环使用该一个变量创建8个Pawn(s)。这怎么可能?而且,我们能否区分从这个变量创建的每个棋子?使用相同的变量名称在for循环中初始化多个对象时会发生什么?

public void setUpChessPieces() { 
    for (int i = 0; i < ChessGame.EIGHT; i++) { 
     //param 1:row, param 2:col, param 3:player#, param4:chess piece color 
     Pawn pawn1 = new Pawn(1, i, 1, "white"); 
     //squares has a setPiece method 
     squares[1][i].setPiece(pawn1); 
    } 
} 
+0

变量“名称”并不是真的那么重要,对许多对象来说都不存在,* *在编译代码中几乎不存在。如果一个对象被多个变量引用,哪一个代表这个对象的“名称”?更重要的是*对象**引用***以及如何获得它们。 –

回答

2

发生了什么会是这样一个简短的厨师下降:

new Pawn(1, i, 1, "white"); 

的JVM分配在堆中的新对象。

Pawn pawn1 = new Pawn(1, i, 1, "white"); 

新分配对象的引用被分配给pawn1。把参考看作一个值,说“在堆中的这个地方查找对象”。

squares[1][i].setPiece(pawn1); 

setPiece正在通过引用Object来调用。

循环终止,pawn1“消失”。这只意味着pawn1本身不再可用。对象本身被存储在堆上,因此不会消失。这个过程重复完成,直到循环完成。

Object被销毁的过程被称为垃圾收集,并且不影响任何仍在使用的对象(如引用存储在pawn1中的对象)。

这些棋子如何区分?
感谢参考。每个对象都存储在堆上的不同位置。所有人必须做的就是比较位置以注意差异(来自JVM内部的POV)。

2

当你说

squares[1][i].setPiece(pawn1); 

你保存你new创建的参考。每次拨打new时,您都会创建一个名为pawn1的临时参考号,但您可以通过前面提到的拨打电话setPiece来进行保存。只要squares有参考,它不是有资格进行垃圾回收。

+0

这意味着每个棋子都有不同的参考,这意味着我将能够移动每个棋子吗?换句话说,所有8个兵都不是同一个? – tragicProgrammer

+0

@tragicProgrammer如前所述,是的。那是对的。 –

2

这怎么可能?

这是可能的,因为在for循环的每次迭代中创建一个pawn实例。 pawn1只是创建的object的标识符。在for循环迭代中创建的每个对象都是存储在堆内存中的独立对象。

Pawn pawn1 = new Pawn(1, i, 1, "white"); 

而且是我们能够区分这 从这个变量,创建每个棋子?

我们可以区分它们的基础数据,而不是pawn1标识符。例如,如果每个pawn对象都覆盖了toString()方法,并且要打印出来,您会发现它们是不同的对象,除非两个不同的对象具有相同的基础数据,那么它们将具有相同的string表示形式。

0

变量只是一个指向对象的指针(或指向任何东西的null)。如果你有一个物理棋盘并用手指指向每个棋子,你可以用同一个指针指向16个不同的对象。在Java中是一样的。

您可以稍后通过维护单独的指针来检索每个对象。您的代码通过将pawn1指针的值复制到每个squares元素中来完成此操作。

循环结束时,pawn1指针(变量)超出范围并消失,但squares引用保持在范围内。

但是,如果您从squares替换值而不复制到之前对象的引用(指针)的某处,那么将永远丢失对该先前对象的最后一个引用,并且它将变得无法访问。

对象不是“从[a]变量创建的”。它们是通过调用new(通常)创建的,并且返回指向结果对象的指针,大概是为了赋值给变量或参与某些操作。您也可以丢弃最终的参考,但这可能是一个错误。

您可以创建一个对象,并将其引用分配给用于保存不同值的相同变量,就像您可以将不同值分配给任何非最终变量,基元或引用一样。

相关问题