2014-12-02 3 views
0

나는 ttt 객체를 복사하고 있는데, ttt 만 변경하려고합니다. 그러나 ttt dunno를 업데이트하면 왜 내 tt를 업데이트하나요? 그것은 내 makechange() 함수에 문제가 있습니까? 이 내 출력자바 복사 객체 및 복사 된 객체 업데이트

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]); 
     } 
    } 
} 

} 

:

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(); 

} 
} 

이이 새로운 클래스 :

메인 클래스입니다

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

이있다 이런 식으로해야 내 예상 출력 :

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

답변

4

=은 객체가 아닌 참조 (포인터) 만 복사하기 때문에 참조하는 실제 객체는 동일합니다. 복사 생성자는 here과 같이 사용하는 것이 좋습니다.

더 자세한 설명 here (약 ArrayList이지만 다른 개체로 추정 할 수 있음)을 읽을 수 있습니다. 그 대답에서

추출 :

B = A

와 b 전체 목록 a를 복사하지 않습니다 염두에 선을 유지하지만 복사 목록에 대한 참조입니다. 이제는 같은 목록에 a와 b 모두 참조 (점) 이 있습니다. 따라서 a.add() 또는 b.add()를 사용하면 을 사용하면 동일한 목록을 수정할 수 있습니다.


Object[][] tt=new Object[2][2];을 수행 할 때 왼쪽 그림은 해당 다음 그림

enter image description here

을 확인, 위의를 이해하는 데 도움합니다. 서클 인 메모리에 Object[2][2] 인스턴스를 만들고 사각형 인 tt이라는 포인터 (참조)를 할당 한 것을 볼 수 있습니다.

오른쪽 다이어그램은 ttt = tt에 해당합니다. 즉, "tt와 동일한 객체를 가리 키도록합니다". 그것은 당신을 위해 아무것도 복사하지 않습니다. 이제 ttttt은 메모리에있는 동일한 객체 인스턴스를 가리 킵니다 (참조). 따라서 tt 또는 ttt을 사용하면 동일한 객체 인스턴스가 수정됩니다.

나는 이것이 당신이하는 일을 분명히하기를 바랍니다. 이를 고치려면 Duncan의 대답에서 설명한대로 어레이의 각 요소를 하나씩 복사해야합니다. 더 일반적으로 복사 생성자를 사용하여 객체 as I linked above을 복사해야합니다.tt정확히 같은 배열

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

이 메소드가 실행 된 후, ttt 포인트 :

+0

당신이 코딩 나에게 자세한 내용을 표시 할 수 있습니다? – hellohai

+0

@hellohai 저는 같은 주제에 관한 또 다른 답변을 연결했습니다. [Java로 객체를 복사하는 것은 처음에는 생각하기 쉽지 않습니다.] (http://stackoverflow.com/questions/869033/how-do-i-copy-an-object-in-java). – m0skit0

+0

대답은 복잡하고 목록 대신 객체와 관련이 없습니다. – hellohai

1

이것은 당신이 배열을 복사하는 방법 하지입니다. 해당 배열에 대한 변경 사항은 두 변수를 통해 볼 수 있습니다.

배열을 올바르게 복사해야합니다. How do I copy a 2 Dimensional array in Java?의 기술을 사용합니다.

+0

나는 전에 이것을 해봤지만 같은 결과를 보여주고있다. – hellohai

+0

@hellohai 시도한 것을 보여주기 위해 질문에있는 코드를 업데이트 해주십시오. –

+1

@hellohai 던컨이 말한 것을 시도한 것 같지 않습니다. – m0skit0

2

=은 두 참조가 모두 동일한 객체를 가리키게합니다. (일반적으로) 복사본을 만들고 싶다면 Java에서 Cloninng (Not Recommended)을 보거나 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

몇 가지 단점이 있지만 걱정하지 마십시오. 책을 확인하는 이유를 정확히 알고 싶다면 Effective Java (모든 Java Developer에 대한 책을 읽어야 함) 항목 11 : 복제를 현명하게 무시하십시오 – javaHunter