o clonă este o copie exactă a originalului. În java, înseamnă în esență capacitatea de a crea un obiect cu o stare similară cu obiectul original. Metoda java clone()
oferă această funcționalitate.
în acest post, vom explora cele mai importante aspecte ale Java clona.
Table of Contents1. What is clone?2. Java Cloneable interface and clone() method3. Shallow Copy4. Deep Copy5. Java Copy Constructors6. Deep copy with serialization7. Cloning using Apache commons8. Java clone best practices
ce este clona Java?
deci clonarea este despre crearea copiei obiectului original. Sensul său de dicționar este : „faceți o copie identică a”.
implicit, clonarea java este ‘field by field copy’, adică deoarece clasa obiect nu are idee despre structura clasei pe care va fi invocată metoda clone ().
deci, JVM când este solicitat pentru clonare, faceți următoarele lucruri:
- dacă clasa are Doar membri primitivi de tip de date, atunci va fi creată o copie complet nouă a obiectului și referința la noua copie a obiectului va fi returnată.
- dacă clasa conține membri de orice tip de clasă, atunci numai referințele de obiect la acei membri sunt copiate și, prin urmare, referințele de membru atât în obiectul original, cât și în obiectul clonat se referă la același obiect.
în afară de comportamentul implicit de mai sus, puteți oricând să suprascrieți acest comportament și să specificați propriul dvs. Acest lucru se face folosind metoda de suprascriere clone()
. Să vedem cum se face.
Java cloneable interface and clone() method
fiecare limbă care acceptă clonarea obiectelor are propriile reguli și la fel și java. În java, dacă o clasă trebuie să accepte clonarea, trebuie să facă următoarele lucruri:
- trebuie să implementați
Cloneable
interfață. - trebuie să înlocuiți
clone()
metoda din clasa de obiecte.
Citește mai mult: interfață Cloneable este rupt în java
documente Java despreclone()
metoda sunt prezentate mai jos (formatat și extract).
- prima declarație garantează că obiectul clonat va avea o atribuire separată a adresei de memorie.
- a doua declarație sugerează că obiectele originale și clonate ar trebui să aibă același tip de clasă, dar nu este obligatorie.a treia afirmație sugerează că obiectele originale și clonate ar fi trebuit să fie egale folosind metoda equals (), dar nu este obligatorie.
să înțelegem clona Java cu exemplu. Prima noastră clasă esteEmployee
clasă cu 3 atribute – id
name
șidepartment
.
Department
clasa are două atribute – id
și name
.
deci, dacă trebuie să clonăm clasa angajaților, atunci trebuie să facem ceva de genul acesta.
mare, am clonat cu succesEmployee
obiect. Dar, amintiți-vă că avem două referințe la același obiect și acum ambele vor schimba starea obiectului în diferite părți ale aplicației. Vrei să vezi cum? Să vedem.
Oops, modificările obiectelor clonate sunt vizibile și în original. În acest fel, obiectele clonate pot face ravagii în sistem dacă li se permite acest lucru. Oricine poate veni și clona obiectele de aplicare și de a face tot ce-i place. Putem preveni acest lucru??
răspunsul este da, putem. Putem preveni acest lucru prin crearea Java deep copy și utilizarea constructorilor de copiere. Vom afla despre ele mai târziu în acest post. Să vedem mai întâi ce este clonarea profundă și clonarea superficială în Java.
Java Shallow Copy
clona Shallow este „implementarea implicită” în Java. În metoda suprascrisă clone
, dacă nu clonați toate tipurile de obiecte (nu primitive), atunci faceți o copie superficială.
toate exemplele de mai sus sunt de copie superficială numai, pentru că nu am clonatDepartment
obiect peEmployee
clasaclone
metoda. Acum, voi trece la următoarea secțiune unde vom vedea clonarea profundă.
Java Deep Copy
clona profundă este comportamentul dorit în majoritatea cazurilor. În copia profundă, creăm o clonă care este independentă de obiectul original și efectuarea modificărilor în obiectul clonat nu ar trebui să afecteze obiectul original.
să vedem cât de profundă copie este creat în Java.
am modificatEmployee
claseclone()
metoda și a adăugat următoareleclone
metoda înDepartment
clasa.
acum testarea codului nostru de clonare dă rezultatul dorit și numele departamentului nu va fi modificat.
aici, schimbarea stării obiectului clonat nu afectează obiectul original.
deci clonarea profundă necesită satisfacerea următoarelor reguli –
- nu este nevoie să copiați separat primitive.
- toate clasele membre din clasa originală ar trebui să sprijine clonarea și în metoda clonă a clasei originale în context ar trebui să apeleze
super.clone()
pe toate clasele membre. - dacă o clasă de membri nu acceptă clonarea, atunci în metoda clonării, trebuie să creați o nouă instanță a acelei clase de membri și să copiați toate atributele sale unul câte unul în obiectul clasei de membri noi. Acest nou obiect de clasă membru va fi setat în obiect clonat.
Citește mai mult: clonarea profundă folosind serializarea în memorie
Java Copy Constructori
Copy constructorii sunt Constructori speciali într-o clasă care are argument pentru propriul tip de clasă. Deci, când treceți o instanță de clasă pentru a copia constructor, atunci constructor va returna o nouă instanță de clasă cu valori copiate din instanța argumentului. Aceasta vă ajută să clona obiect cu interfață Cloneable.
Să vedem acest lucru în exemplul:
public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}
această metodă arată simplu și este până vine moștenire. Când definiți o clasă prin extinderea clasei de mai sus, aveți nevoie pentru a defini un constructor similar acolo, de asemenea. În clasa copil, trebuie să copiați atributele specifice copilului și să transmiteți argumentul constructorului super-clasei. Să vedem cum?
deci, suntem bine acum? Nu. Problema cu moștenirea este că comportamentul exact este identificat numai în timpul rulării. Deci, în cazul nostru, dacă o clasă A trecut instanța PointTwo
în constructor de PointOne
.
în acest caz, veți primi instanța PointOne
în schimb unde ați trecut instanța PointTwo
ca argument. Să vedem acest lucru în Cod:
Un alt mod de a crea un constructor de copiere este de a avea metode statice din fabrică. Ei iau tipul de clasă în argument și creează o nouă instanță folosind un alt constructor al clasei. Apoi, aceste metode din fabrică vor copia toate datele de stare în noua instanță de clasă creată în pasul anterior și vor returna această instanță actualizată.
Java deep copy cu serializare
serializarea este o altă modalitate ușoară de clonare profundă. În această metodă, doar serializați obiectul care urmează să fie clonat și deserializați-l. Evident, obiectul care trebuie clonat ar trebui să implementezeSerializable
interfață.
înainte de a merge mai departe, ar trebui să avertizez că această tehnică nu trebuie utilizată ușor.
- În primul rând, serializarea este extrem de costisitoare. Ar putea fi cu ușurință de o sută de ori mai scump decât metoda
clone()
. - în al doilea rând, nu toate obiectele sunt
Serializable
. - în al treilea rând, a face o clasă
Serializable
este dificil și nu toate clasele pot fi invocate pentru a-l corect.
Citește mai mult: un ghid pentru a pune în aplicare serializare în Java
Java Clone – SerializationUtils
în Apache commons, SerializationUtils
clasa are, de asemenea, funcția de utilitate pentru clonarea profundă. Dacă vă simțiți interesat urmați documentele lor oficiale.
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version></dependency>
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);
java clona cele mai bune practici
- atunci când nu știți dacă puteți apela
clone()
metoda de o anumită clasă ca nu sunteți sigur dacă este implementat în această clasă, puteți verifica cu verificarea dacă clasa este instanță de „Cloneable
” interfață ca mai jos.if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
- Niciun constructor nu este apelat pe obiectul clonat. Drept urmare, este responsabilitatea dvs. să vă asigurați că toți membrii au fost stabiliți corespunzător. De asemenea, dacă țineți evidența numărului de obiecte din sistem prin numărarea invocării constructorilor, aveți un nou loc suplimentar pentru a crește contorul.
sper că această postare a fost o perfecționare pentru dvs. și vă va ajuta să obțineți mai multe informații despre metoda de clonare Java 8 și este utilizarea corectă. Aceasta va ajuta, de asemenea, în răspunsul Java Întrebări interviu clona.
învățare fericită !!