배열에서 clone ()을 호출해도 내용이 복제됩니까?


92

clone()A 유형의 객체 배열에서 메서드를 호출하면 해당 요소를 어떻게 복제합니까? 사본이 동일한 객체를 참조합니까? 아니면 (element of type A).clone()그들 각각을 부를 까요?


3
각 요소에 대해 clone을 호출해야합니다.
Peter Lawrey 2011

답변:


77

clone()얕은 복사본을 만듭니다. 즉, 요소가 복제되지 않습니다. (구현하지 않았다면 Cloneable어떨까요?)

Arrays.copyOf(..)대신에 어레이 복사 에 사용할 수 있습니다 clone()(복제는 다른 것과 달리 어레이에 대해 괜찮습니다)

깊은 복제를 원하면 이 답변을 확인하십시오.


clone()요소가 Cloneable다음 과 같은 경우에도 얕음을 설명하는 간단한 예 :

ArrayList[] array = new ArrayList[] {new ArrayList(), new ArrayList()};
ArrayList[] clone = array.clone();
for (int i = 0; i < clone.length; i ++) {
    System.out.println(System.identityHashCode(array[i]));
    System.out.println(System.identityHashCode(clone[i]));
    System.out.println(System.identityHashCode(array[i].clone()));
    System.out.println("-----");
}

인쇄물:

4384790  
4384790
9634993  
-----  
1641745  
1641745  
11077203  
-----  

2
당신이 그렇게 할 거라고한다면, 개인적으로 내가 사용하는 거라고System.arrayCopy
corsiKa

1
clone()배열과 함께 사용하기에 좋은 옵션입니다. Bloch는 배열에만 사용하고 다른 것은 사용하지 않을 것이라고 언급합니다. System.arrayCopy괜찮습니다. Arrays.copyOf(..)사용하기 쉬운 또 다른 대안입니다.
Bozho 2011

나는 그것을 다시 가져갑니다-나는 사용할 것입니다 Arrays.copyOf:-) 그것은 변수를 단순화하는 메소드 서명을 가지고 있습니다 (예, 그것은 당신을 제한하지만 대부분의 경우에 완벽합니다) 그리고 적어도 내 JDK에서는 System.arrayCopy어쨌든 사용하여 구현됩니다 . 팁 주셔서 감사합니다!
corsiKa 2011

귀하의 예에서 @Bozho. array [i] 및 clone [i]는 동일한 객체를 참조하므로 처음 두 개의 sysout이 동일합니다. 하지만 array [i] .clone은 또한 array [i] 자체를 참조하는데 왜 array [i] .clone ()이 다른 해시 코드 값을 반환합니까?
abhihello123 2013

@weakstudent array[i].clone()array[i]. 그것이 예제의 그 부분이 보여주는 것입니다.
Dathan 2013

19

유형 A의 객체 배열에서 clone () 메서드를 호출하면 해당 요소를 어떻게 복제합니까?

배열의 요소는 복제되지 않습니다.

복사본이 동일한 개체를 참조합니까?

예.

아니면 각각에 대해 (유형 A의 요소) .clone ()을 호출할까요?

아니요, clone()요소를 호출하지 않습니다 .


6

기본 요소의 1D 배열은 복제 될 때 요소를 복사합니다. 이것은 우리가 2D 배열 (Array of Arrays)을 복제하도록 유혹합니다.

의 얕은 복사 구현으로 인해 2D 배열 복제가 작동하지 않습니다 clone().

public static void main(String[] args) {
    int row1[] = {0,1,2,3};
    int row2[] =  row1.clone();
    row2[0] = 10;
    System.out.println(row1[0] == row2[0]); // prints false

    int table1[][]={{0,1,2,3},{11,12,13,14}};
    int table2[][] = table1.clone();
    table2[0][0] = 100;
    System.out.println(table1[0][0] == table2[0][0]); //prints true
}

1
clone1D 프리미티브 배열과 딥 카피를 얻을 수 있다고 말하는 건가요 ? 정말 대단해! 잘 운임 Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar

1
네! 배열이 복제 될 때 원시의 1D 배열이 복사됩니다.
Thamme Gowda

1
Thamme Gowda N은 "primitives"를 말합니다. 객체 배열의 복제는 참조의 복제 일뿐입니다.
Kristiaan

프리미티브는 상태가 없기 때문에 본질적으로 불변입니다. 대한 언급이 없기 때문에 당신은 프리미티브의 단순 복사본을 만들어 질수
Xerus

5

클론은 어레이의 얕은 복사본입니다.

이 테스트 코드는 다음을 인쇄합니다.

[1, 2] / [1, 2]
[100, 200] / [100, 2]

MutableInteger는 두 배열에서 objects[0]및 로 공유 되기 때문에 objects2[0]참조 objects[1]objects2[1].

import java.util.Arrays;                                                                                                                                 

public class CloneTest {                                                                                                                                 
    static class MutableInteger {                                                                                                                        
        int value;                                                                                                                                       
        MutableInteger(int value) {                                                                                                                      
            this.value = value;                                                                                                                          
        }                                                                                                                                                
        @Override                                                                                                                                        
        public String toString() {                                                                                                                       
            return Integer.toString(value);                                                                                                              
        }                                                                                                                                                
    }                                                                                                                                                    
    public static void main(String[] args) {                                                                                                             
        MutableInteger[] objects = new MutableInteger[] {
                new MutableInteger(1), new MutableInteger(2) };                                                
        MutableInteger[] objects2 = objects.clone();                                                                                                     
        System.out.println(Arrays.toString(objects) + " / " + 
                            Arrays.toString(objects2));                                                                
        objects[0].value = 100;                                                                                                                          
        objects[1] = new MutableInteger(200);                                                                                                            
        System.out.println(Arrays.toString(objects) + " / " + 
                            Arrays.toString(objects2));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.