2013-12-22 8 views
0

Из того, что я знаю, объект clone() создает новую копию клонированного объекта. В моем случае я пытаюсь клонировать матрицу Symbol (что является простым enum). this.table - это оригинальный объект, а t - это клон. Когда я напишу новое значение в ячейке t, я бы ожидал, что this.table останется без изменений. Однако это не так, и второйassert не работает. (Я добавил первое утверждение только для обеспечения правильности второго).Object clone() в Java: почему это утверждение терпит неудачу?

Вот код:

@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; 
    } 

Примечание: с отладчиком я проверил, что t и this.table на самом деле имеют разные id, однако после второй проверки, я заметил, что, несмотря на это, их отдельные клетки имеют одинаковый id , Тогда я очень смущен этим. Может ли кто-нибудь объяснить мне, что происходит?

+0

Вам даже не нужен obfuscater! : p – Chiron

+0

Попробуйте добавить 'assert t! = this.table;', поскольку они должны быть разными объектами. – ericbn

ответ

2

У вас есть массив массивов из Symbol экземпляров.

При вызове clone() на this.table, вы получите новый массив, t, но каждый из массивов в t так же, как массив в this.table.

Чтобы проверить это, вы можете попробовать 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]; 
    } 
} 
+0

Я уже делал это, он работает, спасибо в любом случае ;-) – HAL9000

1

Я просто угадываю здесь, но Java делает различие между == и .equals(), и каждый получает один или два раза сжиганием, используя == с некоторой ссылкой на объект, которая действительно нуждается в .equal. Дайте это попробовать ...

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

Вы не можете использовать клон как есть, он не поможет вам, если вы его не реализовали самостоятельно. одинаковый для равных (кроме строк)

Смежные вопросы