Apakah memanggil clone () pada array juga mengkloning isinya?

92

Jika saya memanggil clone()metode pada array Objek tipe A, bagaimana cara mengkloning elemennya? Akankah salinan tersebut merujuk ke objek yang sama? Atau akankah itu memanggil (element of type A).clone()mereka masing-masing?

Szymon
sumber
3
Anda harus memanggil klon pada setiap elemen.
Peter Lawrey

Jawaban:

77

clone()membuat salinan dangkal. Artinya, elemen tersebut tidak akan dikloning. (Bagaimana jika mereka tidak menerapkan Cloneable?)

Anda mungkin ingin menggunakan Arrays.copyOf(..)untuk menyalin larik daripada clone()(meskipun kloning baik-baik saja untuk larik, tidak seperti untuk hal lain)

Jika Anda ingin kloning yang dalam, periksa jawaban ini


Sebuah contoh kecil untuk menggambarkan kedangkalan clone()bahkan jika elemennya adalah 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("-----");
}

Cetakan:

4384790  
4384790
9634993  
-----  
1641745  
1641745  
11077203  
-----  
Bozho
sumber
2
Dan, jika Anda akan melakukan itu, secara pribadi saya akan menggunakanSystem.arrayCopy
corsiKa
1
clone()adalah pilihan yang bagus untuk digunakan dengan array..hampir eksklusif. Bloch menyebutkan bahwa dia akan menggunakannya hanya untuk array dan tidak ada yang lain. System.arrayCopybaik-baik saja. Arrays.copyOf(..)adalah alternatif lain yang lebih mudah digunakan.
Bozho
Saya mengambilnya kembali - saya akan menggunakan Arrays.copyOf:-) Ini memiliki tanda tangan metode yang menyederhanakan variabel (ya itu membatasi Anda, tetapi itu sempurna untuk kebanyakan kasus) dan setidaknya di JDK saya, itu diterapkan dengan System.arrayCopytetap. Terima kasih atas tip itu!
corsiKa
@ Bozho, dari contoh Anda. array [i] dan clone [i] akan merujuk ke objek yang sama sehingga dua sysout pertama sama. Tetapi array [i] .clone juga akan merujuk ke array [i] itu sendiri jadi mengapa array [i] .clone () mengembalikan nilai kode hash yang berbeda?
abhihello123
@weakstudent, array[i].clone()TIDAK mengacu pada array[i]. Itulah yang ditunjukkan oleh bagian dari contoh itu.
Dathan
19

Jika saya memanggil metode clone () pada array Objek tipe A, bagaimana cara mengkloning elemennya?

Elemen array tidak akan digandakan.

Akankah salinan tersebut merujuk ke objek yang sama?

Iya.

Atau akan memanggil (elemen tipe A) .clone () untuk masing-masing?

Tidak, itu tidak akan memanggil clone()salah satu elemen.

Bludzee
sumber
6

Array 1D primitif tidak menyalin elemen saat dikloning. Ini menggoda kita untuk mengkloning array 2D (Array of Arrays).

Ingat bahwa klon array 2D tidak berfungsi karena implementasi salinan dangkal 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
}
Thamme Gowda
sumber
1
Apakah Anda memberi tahu saya bahwa saya bisa clone1D berbagai primitif dan mendapatkan salinan yang dalam? Itu luar biasa! Tarif baik Arrays.copyOfRange(), System.arraycopy()!
Janez Kuhar
1
Yessssss! Array 1D primitif disalin ketika array dikloning
Thamme Gowda
1
Perhatikan bahwa Thamme Gowda N mengatakan "primitif". Klon array objek hanya akan menjadi tiruan referensi.
Kristiaan
karena primitif tidak memiliki status, mereka secara inheren tidak dapat diubah. Anda tidak dapat membuat salinan primitif yang dangkal, karena tidak ada referensi
Xerus
5

Klon adalah salinan larik yang dangkal.

Kode tes ini mencetak:

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

karena MutableIntegerini dibagi dalam kedua larik sebagai objects[0]dan objects2[0], tetapi Anda dapat mengubah referensi objects[1]secara independen dari 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));                                                               
    }                                                                                                                                                    
}                                                                                                                                                        
Simon Nickerson
sumber