2014-12-02 3 views
0

Я копирую объект tt в ttt, и я хочу внести изменения только в ttt, но когда я обновляю ttt, не знаю почему он обновляет мой tt вдоль ???? это моя функция change() возникла проблема?Объект копирования Java и обновленный скопированный объект

это главный класс:

package test; 

public class Test { 

public static void main(String[] args) { 
    Solution sol; 
    sol= new Solution(); 

    sol.add(); 
    sol.copy(); 
    //this makechange function only update ttt only!! 
    sol.makechange(); 
    sol.disOld(); 
    System.out.println("==============="); 
    sol.disNew(); 

} 
} 

это новый класс:

package test; 

import java.util.ArrayList; 
import java.util.List; 

public class Solution { 
Object[][] tt=new Object[2][2]; 
Object[][] ttt=new Object[2][2]; 
List l = new ArrayList<>(); 

public void add(){ 
    l.add(100); 
    tt[0][0]=l; 
    l = new ArrayList<>(); 
    l.add(123); 
    tt[0][1]=l; 
    l = new ArrayList<>(); 
} 

public void disOld(){ 
    for(int i=0; i<tt.length; i++){ 
     for(int j=0; j<tt[i].length; j++){ 
      System.out.println(tt[i][j]); 
     } 
    } 
} 

public void copy(){ 
    ttt=tt; 
} 

public void makechange(){ 
    l.add(99); 
    ttt[1][0]=l; 
} 

public void disNew(){ 
    for(int i=0; i<ttt.length; i++){ 
     for(int j=0; j<ttt[i].length; j++){ 
      System.out.println(ttt[i][j]); 
     } 
    } 
} 

} 

это мой выход:

[100] 
[123] 
[99] 
null 
=============== 
[100] 
[123] 
[99] 
null 

это мой ожидаемый результат должен быть таким:

[100] 
[123] 
null 
null 
=============== 
[100] 
[123] 
[99] 
null 

ответ

4

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

Вы можете прочитать более подробное объяснение here (это около ArrayList, но вы можете экстраполировать на любой другой объект).

Выдержка из этого ответа:

Ь = а

Имейте в виду, эти строки не копирует весь список А до Б, но только копирует ссылки на список. Теперь и a, и b reference (point) в тот же список. Поэтому неважно, используете ли вы a.add() или b.add(), , вы будете изменять тот же список.


Чтобы помочь вам понять выше, проверьте следующую диаграмму

enter image description here

Левая диаграмма соответствует когда вы Object[][] tt=new Object[2][2];. Вы можете увидеть, что вы создаете экземпляр Object[2][2] в памяти, который является кругом, и вы назначаете ему указатель (ссылку): tt, который является прямоугольником.

Правая диаграмма соответствует, когда вы делаете ttt = tt. Это означает: «сделать ttt на том же объекте, что и tt». Он ничего не копирует для вас. Так что теперь и tt, и ttt точка (ссылка) тот же экземпляр объекта в памяти. Поэтому, если вы используете tt или ttt, вы будете изменять один и тот же экземпляр объекта.

Надеюсь, это разъяснит, что вы делаете. Что касается фиксации, вы должны скопировать каждый элемент массива один за другим, как объяснено в ответе Дункана. В более общем плане вы должны использовать конструктор копирования для копирования объектов as I linked above.

+0

вы можете показать мне более подробно в кодировании ?? – hellohai

+0

@hellohai Я связал еще один мой ответ, который посвящен одному и тому же вопросу. [Копирование объектов в Java не так просто, как вы могли бы подумать вначале] (http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java). – m0skit0

+0

Ваш ответ сложный и не связанный с объектом, а не с списками – hellohai

1

Это не как скопировать массив:

public void copy(){ 
    ttt=tt; // booo, hisss, etc. 
} 

После этого выполняется метод, ttt точки на точно так же, как массивtt. Изменения, внесенные в этот массив, видны через обе переменные.

Нужно правильно скопировать массив, например. используя технику от How do I copy a 2 Dimensional array in Java?.

+0

Я попробовал это раньше, но он также показывает тот же результат – hellohai

+0

@hellohai Пожалуйста, обновите код в своем вопросе, чтобы показать, что вы пробовали. –

+1

@hellohai Я не думаю, что вы пробовали то, о чем говорит Дункан. – m0skit0

2

= просто делает обе ссылки указывают на один и тот же объект. Если вы хотите сделать копию (в общем), посмотрите на Cloninng (не рекомендуется) на Java или рассмотрите Copy-Constructor.

Чтобы решить проблему, измените метод копирования на следующее:

public void copy(){ 
    for(int i=0; i<tt.length; i++) 
     for(int j=0; j<tt[i].length; j++) 
      ttt[i][j]= tt[i][j]; 
} 
+0

Клонирование обычно считается [плохой идеей] (http://en.wikipedia.org/wiki/Clone_%28Java_method%29). – m0skit0

+0

Что значит, что клонирование - плохая идея? – hellohai

+1

У этого есть некоторые недостатки, но не беспокойтесь об этом. Если вы хотите точно знать, почему нужно проверять книгу «Эффективная Java» (обязательно читать книгу для каждого Java-разработчика). Пункт 11: разумно переопределить клон – javaHunter

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