Pertimbangkan kode di bawah ini:
DummyBean dum = new DummyBean();
dum.setDummy("foo");
System.out.println(dum.getDummy()); // prints 'foo'
DummyBean dumtwo = dum;
System.out.println(dumtwo.getDummy()); // prints 'foo'
dum.setDummy("bar");
System.out.println(dumtwo.getDummy()); // prints 'bar' but it should print 'foo'
Jadi, saya ingin menyalin dum
ke dumtwo
dan perubahan dum
tanpa mempengaruhi dumtwo
. Tetapi kode di atas tidak melakukan itu. Ketika saya mengubah sesuatu dum
, perubahan yang sama juga terjadi dumtwo
.
Saya kira, ketika saya katakan dumtwo = dum
, Java menyalin referensi saja . Jadi, apakah ada cara untuk membuat salinan baru dum
dan menugaskannya dumtwo
?
Dasar: Menyalin Objek di Jawa.
Mari kita Asumsikan sebuah objek-
obj1
, yang berisi dua objek, containedObj1 dan containedObj2 .menyalin dangkal: menyalin
dangkal menciptakan yang baru
instance
dari kelas yang sama dan menyalin semua bidang ke instance baru dan mengembalikannya. Kelas objek menyediakanclone
metode dan memberikan dukungan untuk penyalinan yang dangkal.Mendalam menyalin:
Salinan mendalam terjadi ketika sebuah benda disalin bersama dengan benda-benda yang diacunya . Gambar di bawah ini menunjukkan
obj1
setelah salinan dalam dilakukan di dalamnya. Tidak hanya telahobj1
disalin , tetapi objek yang terkandung di dalamnya juga disalin. Kita bisa gunakanJava Object Serialization
untuk membuat salinan yang dalam. Sayangnya, pendekatan ini juga memiliki beberapa masalah ( contoh terperinci ).Kemungkinan Masalah:
clone
sulit untuk diterapkan dengan benar.Lebih baik menggunakan menyalin defensif , menyalin konstruktor (sebagai balasan @egaga) atau metode pabrik statis .
clone()
metode publik , tetapi Anda tidak tahu jenis objek pada waktu kompilasi, maka Anda memiliki masalah. Java memiliki antarmuka yang disebutCloneable
. Dalam praktiknya, kita harus mengimplementasikan antarmuka ini jika kita ingin membuat objekCloneable
.Object.clone
adalah dilindungi , jadi kita harus menimpa dengan metode umum dalam rangka untuk itu untuk dapat diakses.clone()
metode semua variabel objek anggota juga menyalin dalam, ini terlalu berisiko asumsi. Anda harus mengontrol kode di semua kelas.Misalnya org.apache.commons.lang.SerializationUtils akan memiliki metode untuk klon mendalam menggunakan serialisasi ( Sumber ). Jika kita perlu mengkloning Bean maka ada beberapa metode utilitas di org.apache.commons.beanutils ( Sumber ).
cloneBean
akan mengkloning kacang berdasarkan pengambil properti dan setter yang tersedia, bahkan jika kelas kacang itu sendiri tidak mengimplementasikan Cloneable.copyProperties
akan menyalin nilai properti dari kacang asal ke kacang tujuan untuk semua kasus di mana nama properti sama.sumber
Dalam paket tersebut
import org.apache.commons.lang.SerializationUtils;
ada metode:Contoh:
sumber
Serializable
Ikuti saja seperti di bawah ini:
dan di mana pun Anda ingin mendapatkan objek lain, lakukan kloning sederhana. misalnya:
sumber
Mengapa tidak ada jawaban untuk menggunakan API Refleksi?
Sangat sederhana.
EDIT: Sertakan objek anak melalui rekursi
sumber
Class A { B child; } Class B{ A parent; }
class car { car car = new car(); }
Saya menggunakan perpustakaan JSON Google untuk membuat cerita bersambung kemudian membuat contoh baru dari objek berseri. Itu salinan dalam dengan beberapa batasan:
tidak ada referensi rekursif
itu tidak akan menyalin array dari tipe yang berbeda
array dan daftar harus diketik atau tidak akan menemukan kelas untuk instantiate
Anda mungkin perlu merangkum string dalam kelas yang Anda nyatakan sendiri
Saya juga menggunakan kelas ini untuk menyimpan preferensi pengguna, windows dan yang lainnya untuk dimuat kembali saat runtime. Sangat mudah digunakan dan efektif.
sumber
Ya, Anda hanya membuat referensi ke objek. Anda dapat mengkloning objek jika mengimplementasikan
Cloneable
.Lihat artikel wiki ini tentang menyalin objek.
Lihat di sini: Menyalin objek
sumber
Tambahkan
Cloneable
dan di bawah kode ke kelas AndaGunakan ini
clonedObject = (YourClass) yourClassObject.clone();
sumber
Iya. Anda perlu Mendalam Salin objek Anda.
sumber
Ini juga berfungsi. Dengan asumsi model
Pertama tambahkan
compile 'com.google.code.gson:gson:2.8.1'
ke aplikasi Anda> gradle & sync. KemudianAnda dapat mengecualikan menggunakan bidang dengan menggunakan
transient
kata kunci setelah pengubah akses.Catatan: Ini praktik buruk. Juga jangan rekomendasikan untuk digunakan
Cloneable
atauJavaSerialization
lambat dan rusak. Tulis copy constructor untuk referensi kinerja terbaik .Sesuatu seperti
Uji statistik iterasi 90000:
Line
UserAccount clone = gson.fromJson(gson.toJson(aO), UserAccount.class);
membutuhkan 808msJalur
UserAccount clone = new UserAccount(aO);
memakan waktu kurang dari 1msKesimpulan: Gunakan gson jika bos Anda gila dan Anda lebih suka kecepatan. Gunakan pembuat salinan kedua jika Anda lebih suka kualitas.
Anda juga dapat menggunakan plugin pembuat kode konstruktor salin di Android Studio.
sumber
Inilah penjelasan yang layak
clone()
jika Anda akhirnya membutuhkannya ...Di sini: clone (metode Java)
sumber
Gunakan utilitas kloning yang dalam:
Ini akan menyalin objek java secara mendalam, memeriksanya di https://github.com/kostaskougios/cloning
sumber
Kloning mendalam adalah jawaban Anda, yang membutuhkan implementasi
Cloneable
antarmuka dan mengesampingkanclone()
metode.Anda akan menyebutnya seperti ini
DummyBean dumtwo = dum.clone();
sumber
dummy
, aString
, tidak dapat diubah, Anda tidak perlu menyalinnyaUntuk melakukan itu, Anda harus mengkloning objek dengan cara tertentu. Meskipun Java memiliki mekanisme kloning, jangan gunakan itu jika Anda tidak perlu. Buat metode penyalinan yang berfungsi untuk Anda, dan kemudian lakukan:
Berikut adalah beberapa saran tentang berbagai teknik untuk menyelesaikan salinan.
sumber
Selain menyalin secara eksplisit, pendekatan lain adalah membuat objek tidak berubah (tidak ada
set
atau metode mutator lainnya). Dengan cara ini, pertanyaan tidak pernah muncul. Kekekalan menjadi lebih sulit dengan benda-benda yang lebih besar, tetapi sisi lain dari hal itu adalah ia mendorong Anda ke arah pemisahan menjadi benda-benda kecil dan komposit yang koheren.sumber
Alternatif untuk metode copy konstruk egaga . Anda mungkin sudah memiliki POJO, jadi tambahkan saja metode lain
copy()
yang mengembalikan salinan objek yang diinisialisasi.Jika Anda sudah memiliki
DummyBean
dan menginginkan salinan:Tapi keduanya bekerja dengan baik, itu akhirnya terserah Anda ...
sumber
sumber
Anda dapat menyalin secara dalam dengan XStream, dari http://x-stream.github.io/ :
Tambahkan ke proyek Anda (jika menggunakan pakar)
Kemudian
Dengan ini, Anda memiliki salinan tanpa perlu mengimplementasikan antarmuka kloning.
sumber
java.beans.XMLEncoder
untuk API Java standar yang bersambung ke XML juga (meskipun tidak tepat untuk keperluan penyalinan dalam).dan dalam kode Anda:
sumber
Lulus objek yang ingin Anda salin dan dapatkan objek yang Anda inginkan:
Sekarang parsing
objDest
ke objek yang diinginkan.Selamat Coding!
sumber
Anda dapat mencoba menerapkan
Cloneable
dan menggunakanclone()
metode ini; Namun, jika Anda menggunakan metode kloning Anda harus - oleh standar - override SELALUObject
'spublic Object clone()
metode.sumber
Jika Anda dapat menambahkan anotasi ke file sumber, prosesor anotasi atau pembuat kode seperti ini dapat digunakan.
Kelas
DummyBeanBuilders
akan menghasilkan, yang memiliki metode statisdummyBeanUpdater
untuk membuat salinan dangkal, dengan cara yang sama seperti yang Anda lakukan secara manual.sumber
Gunakan
gson
untuk menduplikasi objek.Asumsikan saya memiliki objek
person
. Jadisumber