Java clone-deep and shallow copy – costruttori di copia

Un clone è una copia esatta dell’originale. In java, significa essenzialmente la possibilità di creare un oggetto con uno stato simile all’oggetto originale. Il metodo java clone() fornisce questa funzionalità.

In questo post, esploreremo la maggior parte degli aspetti importanti di 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

Che cos’è Java clone?

Quindi la clonazione riguarda la creazione della copia dell’oggetto originale. Il suo significato dizionario è : “fare una copia identica di”.

Per impostazione predefinita, la clonazione java è “copia campo per campo”, ovvero poiché la classe Object non ha idea della struttura della classe su cui verrà invocato il metodo clone ().

Quindi, JVM quando viene chiamato per la clonazione, fai le seguenti cose:

  1. Se la classe ha solo membri di tipo di dati primitivi, verrà creata una copia completamente nuova dell’oggetto e verrà restituito il riferimento alla nuova copia dell’oggetto.
  2. Se la classe contiene membri di qualsiasi tipo di classe, vengono copiati solo i riferimenti all’oggetto a tali membri e quindi i riferimenti ai membri sia nell’oggetto originale che nell’oggetto clonato si riferiscono allo stesso oggetto.

Oltre al comportamento predefinito sopra, puoi sempre ignorare questo comportamento e specificare il tuo. Questo viene fatto usando il metodo override clone(). Vediamo come è fatto.

Java Cloneable interface and clone() method

Ogni lingua che supporta la clonazione di oggetti ha le sue regole e così fa java. In java, se una classe deve supportare la clonazione, deve fare le seguenti cose:

  1. È necessario implementare l’interfacciaCloneable.
  2. È necessario sovrascrivere clone() metodo dalla classe Oggetto.

Per saperne di più: Interfaccia Cloneable è rotto in java

Java documenti suclone() metodo sono riportati di seguito (formattato ed estratto).

  1. La prima istruzione garantisce che l’oggetto clonato avrà un’assegnazione separata dell’indirizzo di memoria.
  2. La seconda istruzione suggerisce che gli oggetti originali e clonati dovrebbero avere lo stesso tipo di classe, ma non è obbligatorio.
  3. La terza istruzione suggerisce che gli oggetti originali e clonati dovrebbero essere uguali usando il metodo equals (), ma non è obbligatorio.

Capiamo Java clone con l’esempio. La nostra prima classe è Employee classe con 3 attributi – idname e department.

Department classe ha due attributi – ide name.

Quindi, se abbiamo bisogno di clonare la classe Employee, allora dobbiamo fare qualcosa di simile.

Ottimo, abbiamo clonato con successo l’oggettoEmployee. Ma, ricorda che abbiamo due riferimenti allo stesso oggetto e ora entrambi cambieranno lo stato dell’oggetto in diverse parti dell’applicazione. Vuoi vedere come? Vediamo.

Oops, le modifiche agli oggetti clonati sono visibili anche nell’originale. In questo modo gli oggetti clonati possono creare scompiglio nel sistema se consentito. Chiunque può venire a clonare gli oggetti dell’applicazione e fare quello che vuole. Possiamo impedirlo??

La risposta è sì, possiamo. Possiamo impedirlo creando Java deep copy e usando i costruttori di copia. Impareremo su di loro più avanti in questo post. Vediamo prima cosa è la clonazione profonda e la clonazione superficiale in Java.

Java Shallow Copy

Shallow clone è “implementazione predefinita” in Java. Nel metodo overridden clone, se non stai clonando tutti i tipi di oggetto (non primitive), stai facendo una copia superficiale.

Tutti gli esempi precedenti sono solo di copia superficiale, perché non abbiamo clonato l’oggetto Department su Employeeclone. Ora, passerò alla prossima sezione dove vedremo la clonazione profonda.

Java Deep Copy

Deep clone è il comportamento desiderato nella maggior parte dei casi. Nella copia profonda, creiamo un clone che è indipendente dall’oggetto originale e apportare modifiche all’oggetto clonato non dovrebbe influire sull’oggetto originale.

Vediamo come viene creata la copia profonda in Java.

Ho modificato il metodo Employee classes clone() e aggiunto il seguente metodo clone nella classe Department.

Ora testando il nostro codice di clonazione dà il risultato desiderato e il nome del reparto non verrà modificato.

Qui, la modifica dello stato dell’oggetto clonato non influisce sull’oggetto originale.

La clonazione così profonda richiede la soddisfazione delle seguenti regole –

  • Non è necessario copiare separatamente le primitive.
  • Tutte le classi membro nella classe originale dovrebbero supportare la clonazione e nel metodo clone della classe originale nel contesto dovrebbero chiamaresuper.clone() su tutte le classi membro.
  • Se una classe membro non supporta la clonazione, nel metodo clone, è necessario creare una nuova istanza di quella classe membro e copiare tutti i suoi attributi uno per uno nell’oggetto new member class. Questo nuovo oggetto classe membro verrà impostato in oggetto clonato.

Per saperne di più: Clonazione profonda utilizzando la serializzazione in memoria

Java Copy Constructors

Copy constructors sono costruttori speciali in una classe che prende argomento per il proprio tipo di classe. Quindi, quando si passa un’istanza di classe a copy constructor, il costruttore restituirà una nuova istanza di classe con valori copiati dall’istanza dell’argomento. Ti aiuta a clonare oggetto con interfaccia Clonabile.

Vediamo questo nell’esempio:

public class PointOne {private Integer x;private Integer y;public PointOne(PointOne point){this.x = point.x;this.y = point.y;}}

Questo metodo sembra semplice ed è fino a quando arriva l’ereditarietà. Quando si definisce una classe estendendo sopra la classe, è necessario definire anche un costruttore simile. Nella classe child, è necessario copiare gli attributi specifici del bambino e passare l’argomento al costruttore della super classe. Vediamo come?

Quindi, stiamo bene ora? No. Il problema con l’ereditarietà è che il comportamento esatto viene identificato solo in fase di runtime. Quindi, nel nostro caso se qualche classe ha passato l’istanza di PointTwo nel costruttore di PointOne.

In questo caso, otterrai l’istanza di PointOnein cambio dove hai passato l’istanza di PointTwo come argomento. Vediamo questo nel codice:

Un altro modo per creare un costruttore di copia è avere metodi di fabbrica statici. Prendono il tipo di classe nell’argomento e creano una nuova istanza usando un altro costruttore della classe. Quindi questi metodi di fabbrica copieranno tutti i dati di stato nella nuova istanza di classe appena creata nel passaggio precedente e restituiranno questa istanza aggiornata.

Java deep copy con serializzazione

La serializzazione è un altro modo semplice di clonazione profonda. In questo metodo, basta serializzare l’oggetto da clonare e de-serializzarlo. Ovviamente, l’oggetto che deve essere clonato dovrebbe implementare l’interfaccia Serializable.

Prima di andare oltre, dovrei avvertire che questa tecnica non deve essere usata alla leggera.

  1. Prima di tutto, la serializzazione è estremamente costosa. Potrebbe facilmente essere cento volte più costoso del metodo clone().
  2. In secondo luogo, non tutti gli oggetti sono Serializable.
  3. In terzo luogo, creare una classe Serializable è complicato e non tutte le classi possono essere invocate per farlo bene.

per saperne di più: Una guida per implementare la serializzazione di Java

clone Java – SerializationUtils

Apache commons, SerializationUtils classe ha anche funzione di utilità per la profondità di clonazione. Se ti senti interessato segui i loro documenti ufficiali.

<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version></dependency>
SomeObject cloned = org.apache.commons.lang.SerializationUtils.clone(someObject);

clone Java best practice

  1. Quando non sai se è possibile chiamare il clone() metodo di una classe particolare, come non si è sicuri se è implementato nella classe, è possibile controllare con il controllo se la classe è un’istanza di “Cloneable” interfaccia come di seguito.
    if(obj1 instanceof Cloneable){ obj2 = obj1.clone();}//Dont do this. Cloneable dont have any methodsobj2 = (Cloneable)obj1.clone();
  2. Nessun costruttore viene chiamato sull’oggetto da clonare. Di conseguenza, è vostra responsabilità, per assicurarsi che tutti i membri sono stati impostati correttamente. Inoltre, se stai tenendo traccia del numero di oggetti nel sistema contando l’invocazione dei costruttori, hai un nuovo posto aggiuntivo per incrementare il contatore.

Spero che questo post sia stato un aggiornamento per te e ti aiuti a ottenere maggiori informazioni sul metodo clone Java 8 e sul suo corretto utilizzo. Aiuterà anche a rispondere alle domande dell’intervista del clone Java.

Buon apprendimento !!

Questo post è stato utile?

Fateci sapere se ti è piaciuto il post. E ‘ l’unico modo per migliorare.
No

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *