Klont der Aufruf von clone () in einem Array auch dessen Inhalt?


92

Wenn ich eine clone()Methode für ein Array von Objekten vom Typ A aufrufe, wie klont sie dann ihre Elemente? Verweist die Kopie auf dieselben Objekte? Oder wird es (element of type A).clone()für jeden von ihnen verlangen ?


3
Sie müssen für jedes Element einen Klon aufrufen.
Peter Lawrey

Antworten:


77

clone()erstellt eine flache Kopie. Dies bedeutet, dass die Elemente nicht geklont werden. (Was ist, wenn sie nicht implementiert haben Cloneable?)

Möglicherweise möchten Sie zum Arrays.copyOf(..)Kopieren von Arrays anstelle von verwenden clone()(obwohl das Klonen für Arrays im Gegensatz zu anderen Elementen in Ordnung ist).

Wenn Sie tiefes Klonen wünschen, überprüfen Sie diese Antwort


Ein kleines Beispiel zur Veranschaulichung der Oberflächlichkeit von clone() selbst wenn die Elemente sind 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("-----");
}

Drucke:

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

2
Und wenn Sie das tun würden, würde ich persönlichSystem.arrayCopy
corsiKa

1
clone()ist eine gute Option für Arrays. Fast ausschließlich. Bloch erwähnt, dass er es nur für Arrays und sonst nichts verwenden würde. System.arrayCopyist gut. Arrays.copyOf(..)ist eine weitere Alternative, die einfacher zu bedienen ist.
Bozho

Ich nehme es zurück - ich würde es benutzen Arrays.copyOf :-) Es hat eine Methodensignatur, die die Variablen vereinfacht (ja, es schränkt Sie ein, aber es ist für die meisten Fälle perfekt) und zumindest in meinem JDK wird es mit implementiert System.arrayCopy. Danke für diesen Tipp!
CorsiKa

@Bozho, von deinem zB. Array [i] und Klon [i] beziehen sich auf dasselbe Objekt, sodass die ersten beiden Sysouts identisch sind. Array [i] .clone würde sich aber auch auf Array [i] selbst beziehen. Warum gibt Array [i] .clone () einen anderen Hashcode-Wert zurück?
Abhihello123

@weakstudent, array[i].clone()bezieht sich NICHT auf array[i]. Das zeigt dieser Teil des Beispiels.
Dathan

19

Wie klone es seine Elemente, wenn ich die Methode clone () für ein Array von Objekten vom Typ A aufrufe?

Die Elemente des Arrays werden nicht geklont.

Verweist die Kopie auf dieselben Objekte?

Ja.

Oder wird es (Element vom Typ A) .clone () für jeden von ihnen aufrufen?

Nein, es wird clone()keines der Elemente aufgerufen .


6

1D-Array von Grundelementen kopiert Elemente, wenn es geklont wird. Dies verleitet uns dazu, ein 2D-Array (Array of Arrays) zu klonen.

Denken Sie daran, dass der 2D-Array-Klon aufgrund der Implementierung einer flachen Kopie von nicht funktioniert 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
Wollen Sie mir sagen, dass ich clone1D-Primitive erstellen und eine tiefe Kopie erhalten kann? Das ist so großartig! Fare gut Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar

1
Yessssss! 1D-Array von
Grundelementen

1
Beachten Sie, dass Thamme Gowda N "Primitive" sagt. Klone von Arrays von Objekten sind nur ein Klon von Referenzen.
Kristiaan

Da Primitive keinen Zustand haben, sind sie von Natur aus unveränderlich. Sie können keine flache Kopie von
Xerus

5

Der Klon ist eine flache Kopie des Arrays.

Dieser Testcode druckt:

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

weil das MutableIntegerin beiden Arrays als objects[0]und geteilt wird objects2[0], aber Sie können die Referenz objects[1]unabhängig von ändern 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));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.