Comprender la clonación de objetos en Java con ejemplos

En este artículo, analizamos la interfaz Cloneable que indica que una clase ha proporcionado un método clone() seguro . Para comprender lo que significa la clonación, recuerde lo que sucede cuando hace una copia de una variable que contiene una referencia de objeto. El original y la copia son referencias al mismo objeto. Esto significa que el original y la copia son mutuamente dependientes, es decir, un cambio en uno provoca también un cambio en el otro.
Si queremos que una copia sea un objeto nuevo que comienza su vida siendo idéntico al original pero cuyo estado puede cambiar con el tiempo debemos utilizar el método clone() .
El método clone() se declara protegido en la clase Object, por lo que nuestro código no puede simplemente llamar a obj.clone() . Ahora podríamos preguntar, pero no se puede acceder a los métodos protegidos desde ninguna subclase y no todas las clases son una subclase de Object . Afortunadamente, las reglas para el acceso protegido son mucho más sutiles. Una subclase puede llamar al método protected clone() para clonar sus propios objetos. Debemos redefinir clon para que sea público y se pueda acceder a él mediante cualquier método. 
Aunque la implementación predeterminada de clone es adecuada, aún necesita implementar la interfaz Cloneable , redefinir el método clone() para que sea público y llamar a public .
Ejemplo: 

Java

class Student implements Cloneable {
 
    // raise visibility level to public
    // and change the return type
    public Student clone()
        throws CloneNotSupportedException
    {
        return (Student)super.clone();
    }
    .
        .
        .
}

El método clone() que acaba de ver no agrega funcionalidad a la copia proporcionada por Object.clone . Simplemente hace que el método sea público y cambia su tipo de retorno . Para hacer una copia más profunda, debemos clonar los campos de la instancia mutable.
Esta es la versión modificada
 

Java

class Student implements Cloneable {
 
    // other components
 
    public Student clone()
        throws CloneNotSupportedException
    {
 
        // call Object.clone()
        Student obj = (Student)super.clone();
 
        // clone mutable fields
        obj.birthDay = (Date)birthDay.clone();
    }
}

El método clone() de Object intentará generar una ClassNotSupportedException cada vez que se invoque clon en una clase que no implemente la interfaz Cloneable .
Ejemplo: 
 

Java

import java.util.Date;
import java.util.GregorianCalendar;
 
public class Employee implements Cloneable {
 
    private String name;
    private double salary;
    private Date hireDay;
 
    public Employee(String name, double salary)
    {
        this.name = name;
        this.salary = salary;
        hireDay = new Date();
    }
 
    public Employee clone()
        throws CloneNotSupportedException
    {
 
        // call Object.clone()
        Employee obj = (Employee)super.clone();
 
        // clone mutable fields
        obj.hireDay = (Date)hireDay.clone();
 
        return obj;
    }
 
    // Set the hireDay to a given date
    public void setHireDay(int year, int month, int day)
    {
 
        Date newHireDay
            = new GregorianCalendar(year,
                                    month - 1,
                                    day)
                  .getTime();
 
        // instance field mutation
        hireDay.setTime(newHireDay.getTime());
    }
 
    public void raiseSalary(double byPercent)
    {
 
        double raise = salary * byPercent / 100;
        salary += raise;
    }
 
    public String toString()
    {
        return ("Employee[name=" + name
                + ", salary=" + salary
                + ", hireDay=" + hireDay
                + "]");
    }
 
    // main
    public static void main(String[] args)
    {
 
        try {
 
            Employee original
                = new Employee("ABC X. YZ", 50000);
 
            original.setHireDay(2000, 1, 1);
            Employee copy = original.clone();
 
            copy.raiseSalary(10);
            copy.setHireDay(2002, 12, 31);
 
            System.out.println("original= " + original);
            System.out.println("copy= " + copy);
        }
 
        catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
Salida:
original = Empleado [nombre = ABC X. YZ, salario = 50000.0, día de contratación = sábado 01 de enero 00:00:00 UTC 2000] 
copia = Empleado [nombre = ABC X. YZ, salario = 55000.0, día de contratación = martes 31 de diciembre 00:00:00UTC 2002]
 

Ventajas de la clonación: 

  • En Java, el operador ‘=’ (asignación) no se puede utilizar para la clonación, ya que simplemente crea una copia de las variables de referencia. Para superar tal discrepancia , se puede usar el método clone() de la clase Object sobre el operador de asignación.
  • El método clone() es un método protegido de la clase Object , lo que significa que solo la clase Employee puede clonar objetos Employee. Esto significa que ninguna clase que no sea Empleado puede clonar objetos Empleado ya que no conoce los atributos de la clase Empleado.

Aplicación de Clonación en Java

  • Permite la copia campo por campo de objetos, lo que resulta útil cuando se trata de objetos de características similares.
  • El método clone() predeterminado se puede reparar llamando a clon en subobjetos mutables.

Publicación traducida automáticamente

Artículo escrito por da_grt_aru y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *