Java中的对象clone():为什么这个断言失败了?

时间:2013-12-22 21:27:34

标签: java

据我所知,对象clone()创建了克隆对象的新副本。就我而言,我正在尝试克隆Symbol的矩阵(这是一个简单的enum)。 this.table是原始对象,而t是克隆。当我将新值写入t的单元格时,我希望this.table保持不变。但情况并非如此,第二个 assert失败。 (我添加了第一个断言只是为了确保第二个断言的正确性。)

以下是代码:

@Override
    public State applyAction(Action action) { 
            int x = ((TickAction)action).x;
            int y = ((TickAction)action).y; 
        Symbol[][] t = this.table.clone();
        assert this.table[x][y] != currentPlayer.getSymbol();

        t[x][y] = currentPlayer.getSymbol();

        assert t[x][y] != this.table[x][y] ;

        TableState ts = new TableState(t,this.currentPlayer.getNextPlayer());
        ts.setLastAction(action);
        return ts;
    }

注意:使用调试器我检查tthis.table实际上有不同的id,但是经过第二次检查后,我注意到,尽管如此,他们的单个单元格具有相同的{{ 1}}。然后我对此感到困惑。有人能解释我发生了什么吗?

3 个答案:

答案 0 :(得分:2)

您有一组Symbol个实例的数组。

当您在clone()上致电this.table时,您会获得一个新数组t,但t中的每个数组都与this.table中的数组相同1}}。

为了检查这一点,您可以尝试assert t[0] == this.table[0];

为了获得更深层次的克隆,您必须创建一个新数组并自行初始化:

Symbol[][] t = new Symbol[][this.table.length];
for (int i = 0; i < t.length; i++)
{
    t[i] = new Symbol[this.table[i].length];
    for (int j = 0; j < t[i].length; j++)
    {
        // Here I am sharing the Symbol objects between the two arrays.
        // If you do not want that, define your own way to copy or clone the object.
        t[i][j] = this.table[i][j];
    }
}

答案 1 :(得分:1)

我只是在这里猜测,但Java对==和.equals()进行了区分,并且每个人都使用==使用一些实际需要的对象引用来烧毁一次或两次.equal。试一试......

assert this.table[((TickAction)action).x][((TickAction)action).y].equals( currentPlayer.getSymbol() );

答案 2 :(得分:1)

你不能按原样使用克隆,如果你没有自己实现它,它不会帮助你。 对于equals(字符串除外)相同