en klone er en eksakt kopi av originalen. I java betyr det i hovedsak evnen til å skape et objekt med lignende tilstand som det opprinnelige objektet. Java clone()
– metoden gir denne funksjonaliteten.
i dette innlegget vil vi utforske de fleste viktige aspekter Av Java klone.
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
Hva Er Java-klone?
så kloning handler om å lage kopien av originalt objekt. Dens ordbok betydning er : «lag en identisk kopi av».som standard er java kloning ‘felt for feltkopi’, dvs. Som Objektklassen ikke har ide om strukturen i klassen som clone () – metoden vil bli påkalt.
Så, JVM når kalt for kloning, gjør følgende ting:
- hvis klassen bare har primitive datatypemedlemmer, vil en helt ny kopi av objektet bli opprettet, og referansen til den nye objektkopien vil bli returnert.
- hvis klassen inneholder medlemmer av en hvilken som helst klassetype, kopieres kun objektreferansene til disse medlemmene, og dermed refererer medlemsreferansene i både det opprinnelige objektet og det klonede objektet til det samme objektet.
Bortsett fra over standard virkemåte, kan du alltid overstyre denne virkemåten og angi din egen. Dette gjøres ved å overstyreclone()
– metoden. La oss se hvordan det er gjort.
Java Cloneable interface and clone() method
Alle språk som støtter kloning av objekter har sine egne regler og det gjør java. I java, hvis en klasse trenger å støtte kloning, må den gjøre følgende ting:
- Du må implementere
Cloneable
grensesnitt. - Du må overstyre
clone()
metode Fra Objektklasse.
Les mer: Kloneable grensesnitt er brutt i java
Java docs omclone()
metoden er gitt nedenfor (formatert og pakke ut).
- Første setning garanterer at klonet objekt vil ha separat minneadressetilordning.
- Andre setning antyder at originale og klonede objekter skal ha samme klassetype, men det er ikke obligatorisk.
- Tredje setning antyder at originale og klonede objekter skal være like ved hjelp av equals () – metoden, men det er ikke obligatorisk.
La oss forstå Java klone med eksempel. Vår første klasse er Employee
klasse med 3 attributter – id
name
ogdepartment
.
Department
klassen har to attributter- id
og name
.
Så, Hvis Vi trenger å klone Medarbeiderklassen, må vi gjøre noe slikt.
Flott, vi klarte å kloneEmployee
objektet. Men husk at vi har to referanser til samme objekt, og nå vil begge endre tilstanden til objektet i ulike deler av søknaden. Vil du se hvordan? La oss se.
Oops, klonede objektendringer er synlige i original også. På denne måten klonede objekter kan gjøre kaos i systemet hvis lov til å gjøre det. Hvem som helst kan komme og klone applikasjonsobjektene dine og gjøre hva han vil. Kan vi forhindre dette??
Svaret er ja, vi kan. Vi kan forhindre dette ved å lage Java deep copy og bruke copy constructors. Vi vil lære om dem senere i dette innlegget. La oss først se hva som er dyp kloning og grunne kloning I Java.
Java Grunne Kopi
Grunne klone er «standard implementering» I Java. I overstyrt clone
– metoden, hvis du ikke kloner alle objekttyper (ikke primitiver), lager du en grunne kopi.
alle eksemplene ovenfor er bare grunne kopier, fordi vi ikke har klonet Department
– objektet på Employee
klassens clone
– metoden. Nå vil jeg gå videre til neste avsnitt hvor vi vil se den dype kloning.
Java Deep Copy
Deep clone er ønsket oppførsel i de fleste tilfeller. I den dype kopien lager vi en klone som er uavhengig av det opprinnelige objektet, og endringer i det klonede objektet skal ikke påvirke det opprinnelige objektet.
La se hvor dyp kopi er opprettet I Java.
jeg endret Employee
klasser clone()
metode og lagt til følgende clone
metode i Department
klasse.
nå tester vår kloningskode gir ønsket resultat og navnet på avdelingen vil ikke bli endret.
her påvirker ikke endring av tilstanden til det klonede objektet det opprinnelige objektet.
så dyp kloning krever tilfredsstillelse av følgende regler –
- Du trenger ikke å kopiere primitiver separat.
- alle medlemsklassene i originalklassen skal støtte kloning, og i klonemetode i originalklassen skal i sammenheng kalle
super.clone()
på alle medlemsklasser. - Hvis en medlemsklasse ikke støtter kloning, må man opprette en ny forekomst av denne medlemsklassen og kopiere alle dens attributter en etter en til nytt medlemsklasseobjekt. Dette nye medlemsklasseobjektet vil bli satt i klonet objekt.
Les mer: Dyp kloning ved hjelp av in-memory serialisering
Java Copy Constructors
Copy constructors er spesielle konstruktører i en klasse som tar argument for sin egen klassetype. Så, når du sender en forekomst av klasse til å kopiere konstruktør, vil konstruktør returnere en ny forekomst av klasse med verdier kopiert fra argumentinstans. Det hjelper deg å klone objekt Med Kloneable grensesnitt.
Lar se dette i eksempel:
public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}
denne metoden ser enkel ut og det er til kommer arv. Når du definerer en klasse ved å utvide over klassen, må du definere en lignende konstruktør der også. I barneklassen må du kopiere barnespesifikke attributter og sende argumentet til superklassens konstruktør. La oss se hvordan?
så, er vi fine nå? INGEN. Problemet med arv er at nøyaktig oppførsel bare identifiseres ved kjøretid. Så, i vårt tilfelle hvis noen klasse passerte forekomsten av PointTwo
i konstruktør av PointOne
.
I dette tilfellet vil du få forekomsten av PointOne
i retur der du passerte forekomsten av PointTwo
som argument. Kan se dette i kode:
En Annen måte å lage en kopi konstruktør er å ha statiske fabrikkmetoder. De tar klassetype i argument og oppretter en ny forekomst ved hjelp av en annen konstruktor av klassen. Da vil disse fabrikkmetodene kopiere alle statsdataene til ny klasseforekomst som nettopp ble opprettet i forrige trinn, og returnere denne oppdaterte forekomsten.
Java deep copy med serialisering
Serialisering er en annen enkel måte å dype kloning. I denne metoden serialiserer du bare objektet som skal klones og de-serialiserer det. Åpenbart må objektet som må klones implementereSerializable
grensesnitt.
Før jeg går videre, bør jeg være forsiktig med at denne teknikken ikke skal brukes lett.
- først av alt er serialisering enormt dyrt. Det kan lett være hundre ganger dyrere enn
clone()
– metoden. - For Det Andre er ikke alle objekter
Serializable
. - Tredje, å lage en klasse
Serializable
er vanskelig og ikke alle klasser kan stole på å få det riktig.
Les mer: en guide for å implementere serialisering I Java
Java clone – SerializationUtils
I Apache commons, SerializationUtils
klassen har også verktøyet funksjon for dyp kloning. Hvis du føler deg interessert, følg deres offisielle dokumenter.
<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 clone best practices
- når du ikke vet om du kan ringe
clone()
metode for en bestemt klasse som du ikke er sikker på om den er implementert i den klassen, kan du sjekke med å sjekke om klassen er forekomst av «Cloneable
» grensesnitt som nedenfor.if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
- ingen konstruktør kalles på objektet som klones. Som et resultat er det ditt ansvar å sørge for at alle medlemmene er riktig satt. Også, hvis du holder styr på antall objekter i systemet ved å telle påkallingen av konstruktører, fikk du et nytt ekstra sted for å øke telleren.
jeg håper at dette innlegget har vært en oppfriskning for deg og hjelpe deg å få mer informasjon Om Java 8 klonemetode og det er riktig bruk. Det vil også hjelpe i å svare Java klone intervju spørsmål.
God Læring !!