Java clone – dybe og lavvandede copy – copy constructors

en klon er en nøjagtig kopi af originalen. I java betyder det i det væsentlige evnen til at oprette et objekt med lignende tilstand som det oprindelige objekt. Javaclone() metoden giver denne funktionalitet.

i dette indlæg vil vi udforske de fleste af de vigtige aspekter af Java clone.

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

Hvad er Java klon?

så kloning handler om at oprette kopien af det originale objekt. Dens ordbog betydning er : “lav en identisk kopi af”.

som standard er java-kloning ‘felt for feltkopi’, dvs.da Objektklassen ikke har en ide om strukturen i klassen, hvorpå klon () – metoden vil blive påberåbt.

så, JVM når der kræves kloning, skal du gøre følgende ting:

  1. hvis klassen kun har primitive datatypemedlemmer, oprettes en helt ny kopi af objektet, og henvisningen til den nye objektkopi returneres.
  2. hvis klassen indeholder medlemmer af en hvilken som helst klassetype, kopieres kun objekthenvisningerne til disse medlemmer, og derfor henviser medlemshenvisningerne i både det originale objekt såvel som det klonede objekt til det samme objekt.

bortset fra ovenstående standardadfærd kan du altid tilsidesætte denne adfærd og angive din egen. Dette gøres ved hjælp af overordnetclone() metode. Lad os se, hvordan det gøres.

Java Cloneable interface and clone() method

hvert sprog, der understøtter kloning af objekter, har sine egne regler, og det gør java også. I java, Hvis en klasse skal understøtte kloning, skal den gøre følgende ting:

  1. du skal implementereCloneable interface.
  2. du skal tilsidesætte clone() metode fra objektklasse.

Læs mere: Cloneable interface er brudt i java

Java docs about clone() metoden er angivet nedenfor (formateret og uddrag).

  1. første erklæring garanterer, at klonet objekt vil have separat hukommelse adressetildeling.
  2. anden erklæring antyder, at originale og klonede objekter skal have samme klassetype, men det er ikke obligatorisk.
  3. tredje sætning tyder på, at originale og klonede objekter skal være ens ved hjælp af lig med () metode, men det er ikke obligatorisk.

lad os forstå Java klon med eksempel. Vores første klasse er Employee klasse med 3 attributter – idname og department.

Department klasse har to attributter – id ogname.

så hvis vi skal klone medarbejderklassen, så skal vi gøre noget som dette.

fantastisk, vi klonede med succes Employee objekt. Men husk, at vi har to henvisninger til det samme objekt, og nu vil begge ændre objektets tilstand i forskellige dele af applikationen. Vil du se hvordan? Lad os se.

ups, klonede objekt ændringer er synlige i original også. På denne måde kan klonede objekter gøre kaos i systemet, hvis de får lov til det. Alle kan komme og klone dine applikationsobjekter og gøre hvad han vil. Kan vi forhindre dette??

svaret er ja, det kan vi. Vi kan forhindre dette ved at oprette Java deep copy og bruge copy constructors. Vi lærer om dem senere i dette indlæg. Lad os først se, hvad der er dyb kloning og lavvandet kloning i Java.

Java lavvandede kopi

lavvandede klon er “standard implementering” i Java. I tilsidesatclone metode, hvis du ikke kloner alle objekttyper (ikke primitiver), så laver du en lav kopi.

alle ovenstående eksempler er kun af lav kopi, fordi vi ikke har klonet Departmentobjekt påEmployeeklassensclone metode. Nu vil jeg gå videre til næste afsnit, hvor vi vil se den dybe kloning.

Java Deep Copy

Deep clone er den ønskede adfærd i de fleste tilfælde. I den dybe kopi opretter vi en klon, der er uafhængig af det originale objekt, og at foretage ændringer i det klonede objekt bør ikke påvirke det originale objekt.

lad se, hvor dyb kopi er oprettet i Java.

Jeg ændrede Employeeklasserclone()metode og tilføjet følgendeclonemetode iDepartment klasse.

nu tester vores kloning kode giver det ønskede resultat og navnet på afdelingen vil ikke blive ændret.

Her påvirker ændring af tilstanden for det klonede objekt ikke det oprindelige objekt.

så dyb kloning kræver tilfredshed med følgende regler –

  • ingen grund til separat at kopiere primitiver.
  • Alle medlemsklasser i original klasse skal understøtte kloning og i klonmetode for original klasse i kontekst skal kalde super.clone() på alle medlemsklasser.
  • hvis en medlemsklasse ikke understøtter kloning, skal man i klonmetoden oprette en ny forekomst af den pågældende medlemsklasse og kopiere alle dens attributter en efter en til nyt medlemsklasseobjekt. Dette nye medlemsklasseobjekt indstilles i klonet objekt.

Læs mere: dyb kloning ved hjælp af serialisering i hukommelsen

Java Copy Constructors

Copy constructors er specielle konstruktører i en klasse, der tager argument for sin egen klassetype. Så når du passerer en forekomst af klasse for at kopiere konstruktør, returnerer konstruktør en ny forekomst af klasse med værdier kopieret fra argumentforekomst. Det hjælper dig med at klone objekt med Cloneable interface.

lad os 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 metode ser enkel ud, og den er indtil arv kommer. Når du definerer en klasse ved at udvide over klassen, skal du definere en lignende konstruktør der også. I barn klasse, skal du kopiere barn specifikke attributter og videregive argumentet til super klasse konstruktør. Lad os se hvordan?

så har vi det godt nu? INGEN. Problemet med arv er, at nøjagtig adfærd kun identificeres ved kørsel. Så i vores tilfælde, hvis en klasse bestod forekomsten af PointTwo i konstruktør af PointOne.

i dette tilfælde får du forekomsten afPointOnetil gengæld hvor du bestod forekomst afPointTwo som argument. Lad os se dette i kode:

en anden måde at oprette en kopikonstruktør på er at have statiske fabriksmetoder. De tager klasse type I argument og oprette en ny instans ved hjælp af en anden konstruktør af klassen. Derefter kopierer disse fabriksmetoder alle statsdata til ny klasseinstans, der netop er oprettet i det foregående trin, og returnerer denne opdaterede instans.

Java deep copy med serialisering

serialisering er en anden nem måde at Dyb kloning på. I denne metode serialiserer du bare det objekt, der skal klones, og de-serialiserer det. Det er klart, at objektet, der skal klones, skal implementere Serializable interface.

før jeg går videre, skal jeg advare om, at denne teknik ikke skal bruges let.

  1. først og fremmest er serialisering enormt dyrt. Det kunne nemt være hundrede gange dyrere end clone() – metoden.
  2. for det andet er ikke alle objekterSerializable.
  3. for det tredje, at lave en klasse Serializable er vanskelig, og ikke alle klasser kan påberåbes for at få det rigtigt.

Læs mere: en guide til implementering af serialisering i Java

Java klon – Serialiseringutils

i Apache commons,SerializationUtils klasse har også hjælpefunktion til dyb kloning. Hvis du føler dig interesseret i at følge deres officielle 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

  1. når du ikke ved, om du kan ringe til clone() metode til en bestemt klasse, da du ikke er sikker på, om den er implementeret i den klasse, kan du tjekke med at kontrollere, om du kan klassen er forekomst af “Cloneable” interface som nedenfor.
    if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
  2. ingen konstruktør kaldes på objektet, der klones. Som resultat, det er dit ansvar, at sikre, at alle medlemmer er indstillet korrekt. Også, hvis du holder styr på antallet af objekter i systemet ved at tælle påkaldelsen af konstruktører, har du et nyt ekstra sted at øge tælleren.

Jeg håber, at dette indlæg har været en genopfriskning for dig og hjælper dig med at få mere information om Java 8 klonmetode, og det er korrekt brug. Det vil også hjælpe med at besvare Java klon samtale spørgsmål.

glad læring !!

var dette indlæg nyttigt?

fortæl os, hvis du kunne lide indlægget. Det er den eneste måde, vi kan forbedre.
Ja
Nej

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *