een kloon is een exacte kopie van het origineel. In java betekent het in wezen de mogelijkheid om een object te maken met dezelfde status als het oorspronkelijke object. De java clone()
methode biedt deze functionaliteit.
In dit bericht zullen we de meeste belangrijke aspecten van Java clone onderzoeken.
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
Wat is Java-kloon?
dus klonen gaat over het maken van de kopie van het oorspronkelijke object. Zijn woordenboek betekenis is : “Maak een identieke kopie van”.
standaard is het klonen van java ‘field by field copy’, d.w.z. omdat de objectklasse geen idee heeft over de structuur van de klasse waarop de clone() methode zal worden aangeroepen.
So, JVM als u wordt opgeroepen voor klonen, doe dan de volgende dingen:
- als de klasse alleen primitieve data type leden heeft dan zal een volledig nieuwe kopie van het object worden gemaakt en zal de verwijzing naar de nieuwe object kopie worden geretourneerd.
- als de klasse leden van een klasse-type bevat, worden alleen de objectverwijzingen naar die leden gekopieerd en dus verwijzen de lidverwijzingen in zowel het originele object als het gekloonde object naar hetzelfde object.
afgezien van het bovenstaande standaardgedrag, kunt u dit gedrag altijd overschrijven en uw eigen gedrag opgeven. Dit wordt gedaan met de overschrijvende clone()
methode. Eens kijken hoe het moet.
Java Cloneable interface and clone() method
elke taal die klonen van objecten ondersteunt heeft zijn eigen regels en java ook. In java, als een klasse klonen moet ondersteunen, moet het de volgende dingen doen:
- u moet
Cloneable
interface implementeren. - u moet de methode
clone()
overschrijven vanuit objectklasse.
Lees meer: Cloneable interface is broken in java
Java docs about clone()
methode worden hieronder gegeven (geformatteerd en extract).
- eerste statement garandeert dat gekloond object een aparte geheugenadressetoewijzing heeft.
- tweede statement suggereert dat Originele en gekloonde objecten hetzelfde class type moeten hebben, maar het is niet verplicht.
- derde statement suggereert dat Originele en gekloonde objecten gelijk moeten zijn met behulp van de methode equals (), maar het is niet verplicht.
laten we Java clone met voorbeeld begrijpen. Onze eerste klasse is Employee
klasse met 3 attributen – id
name
en department
.
Department
klasse heeft twee attributen – id
en name
.
dus, als we de Employee class moeten klonen, dan moeten we iets als dit doen.
geweldig, we hebben met succes hetEmployee
object gekloond. Maar vergeet niet dat we twee verwijzingen naar hetzelfde object hebben en nu beide de toestand van het object in verschillende delen van de toepassing veranderen. Wil je zien hoe? Eens kijken.
Oops, gekloonde objectwijzigingen zijn ook zichtbaar in het origineel. Op deze manier kunnen gekloonde objecten schade aanrichten in het systeem als dat toegestaan wordt. Iedereen kan je applicatieobjecten komen klonen en doen wat hij wil. Kunnen we dit voorkomen??
antwoord is ja, dat kunnen we. We kunnen dit voorkomen door Java deep copy te maken en copy constructors te gebruiken. We zullen er later in dit bericht over leren. Laten we eerst eens kijken wat diep klonen en ondiep klonen in Java is.
Java Shallow Copy
Shallow clone is “standaard implementatie” in Java. In overschrijdende clone
methode, als u niet alle objecttypes (geen primitieven) klonen, dan maakt u een ondiepe kopie.
alle bovenstaande voorbeelden zijn alleen van ondiep kopiëren, omdat we het Department
object niet hebben gekloond op Employee
class clone
methode. Nu ga ik verder met de volgende sectie waar we het diepe klonen zullen zien.
Java Deep Copy
Deep clone is in de meeste gevallen het gewenste gedrag. In de diepe kopie maken we een kloon die onafhankelijk is van het oorspronkelijke object en het maken van veranderingen in het gekloonde object mag het oorspronkelijke object niet beïnvloeden.
laat zien hoe diep kopiëren wordt gemaakt in Java.
Ik heb de Employee
klassen clone()
methode gewijzigd en toegevoegd na clone
methode in Department
klasse.
het testen van onze klonen code geeft het gewenste resultaat en de naam van de afdeling zal niet worden gewijzigd.
Hier heeft het wijzigen van de status van het gekloonde object geen invloed op het oorspronkelijke object.
so deep cloning requires satisfaction of following rules –
- Het is niet nodig om primitieven afzonderlijk te kopiëren.
- alle ledenklassen in de oorspronkelijke klasse zouden klonen moeten ondersteunen en in de kloon methode van de oorspronkelijke klasse in context zou
super.clone()
op alle ledenklassen moeten aanroepen. - als een member class klonen niet ondersteunt, moet men in de kloon methode een nieuwe instantie van die member class aanmaken en alle attributen één voor één kopiëren naar een nieuw member class object. Dit nieuwe lid klasse object zal worden ingesteld in gekloond object.
Lees meer: Deep cloning using in-memory serialization
Java Copy Constructors
Copy constructors zijn speciale constructors in een klasse die argumenten heeft voor zijn eigen klasse type. Dus als je een instantie van klasse doorgeeft aan copy constructor, dan zal constructor een nieuwe instantie van klasse retourneren met waarden gekopieerd van argument instantie. Het helpt u om te klonen object met Cloneable interface.
laat dit zien in voorbeeld:
public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}
deze methode ziet er eenvoudig uit en het is totdat er overerving komt. Wanneer u een klasse definiëren door uit te breiden boven klasse, moet u een soortgelijke constructor daar ook definiëren. In de kinderklasse moet u kindspecifieke kenmerken kopiëren en het argument doorgeven aan de constructor van de superklasse. Eens kijken hoe?
zijn we nu in orde? GEEN. Het probleem met overerving is dat exact gedrag alleen wordt geà dentificeerd tijdens runtime. Dus, in ons geval als een klasse de instantie van PointTwo
passeerde in constructor van PointOne
.
in dit geval krijgt u de instantie van PointOne
in ruil waar u de instantie van PointTwo
passeerde als argument. Laat dit eens zien in code:
een andere manier om een copy constructor aan te maken is door statische fabrieksmethoden te hebben. Ze nemen class type in argument en maken een nieuwe instantie met behulp van een andere constructor van de klasse. Vervolgens kopiëren deze fabrieksmethoden alle statusgegevens naar een nieuwe klasse-instantie die zojuist is gemaakt in de vorige stap en retourneren deze bijgewerkte instantie.
Java deep copy met serialisatie
serialisatie is een andere eenvoudige manier van deep cloning. In deze methode, je gewoon serialiseren het object te worden gekloond en de-serialiseren het. Het is duidelijk dat het object dat gekloond moet worden Serializable
interface moet implementeren.
alvorens verder te gaan, moet ik oppassen dat deze techniek niet lichtvaardig wordt gebruikt.
- Allereerst is serialisatie enorm duur. Het kan gemakkelijk honderd keer duurder zijn dan de
clone()
methode. - ten tweede zijn niet alle objecten
Serializable
. - Ten derde is het maken van een klasse
Serializable
lastig en niet alle klassen kunnen worden gebruikt om het goed te krijgen.
Lees Meer: a guide to implementate serialization in Java
Java clone – SerializationUtils
in Apache commons heeft SerializationUtils
klasse ook een utility functie voor diep klonen. Als je geïnteresseerd bent, volg dan hun officiële documenten.
<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
- wanneer u niet weet of u de
clone()
methode van een bepaalde klasse kunt aanroepen omdat u niet zeker weet of het in die klasse is geïmplementeerd, kunt u controleren of de klasse instance van “Cloneable
” interface zoals hieronder.if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
- Er wordt geen constructor aangeroepen op het object dat wordt gekloond. Als gevolg daarvan is het uw verantwoordelijkheid om ervoor te zorgen dat alle leden goed zijn ingesteld. Ook, als u het bijhouden van het aantal objecten in het systeem door het tellen van de aanroep van constructeurs, je kreeg een nieuwe extra plaats om de teller te verhogen.
Ik hoop dat dit bericht een opfriscursus voor u is geweest en U helpt meer informatie te krijgen over de Java 8 kloon methode en het juiste gebruik. Het zal ook helpen bij het beantwoorden van Java clone interview vragen.
Gelukkig leren !!