Constructeur de copie Java

1. Introduction

Un constructeur de copie dans une classe Java est un constructeur qui crée un objet à l'aide d'un autre objet de la même classe Java .

C'est utile lorsque nous voulons copier un objet complexe qui a plusieurs champs, ou lorsque nous voulons faire une copie complète d'un objet existant.

2. Comment créer un constructeur de copie

Pour créer un constructeur de copie, nous pouvons d'abord déclarer un constructeur qui prend un objet du même type comme paramètre:

public class Employee { private int id; private String name; public Employee(Employee employee) { } }

Ensuite, nous copions chaque champ de l'objet d'entrée dans la nouvelle instance:

public class Employee { private int id; private String name; public Employee(Employee employee) { this.id = employee.id; this.name = employee.name; } }

Ce que nous avons ici est une copie superficielle , ce qui est très bien puisque tous nos champs - un int et une chaîne dans ce cas - sont soit des types primitifs, soit des types immuables.

Si la classe Java a des champs mutables, nous pouvons à la place faire une copie complète à l' intérieur de son constructeur de copie. Avec une copie complète, l'objet nouvellement créé est indépendant de l'original car nous créons une copie distincte de chaque objet mutable:

public class Employee { private int id; private String name; private Date startDate; public Employee(Employee employee) { this.id = employee.id; this.name = employee.name; this.startDate = new Date(employee.startDate.getTime()); } }

3. Copier le constructeur contre le clone

En Java, nous pouvons également utiliser la méthode clone pour créer un objet à partir d'un objet existant. Cependant, le constructeur de copie présente certains avantages par rapport à la méthode de clonage :

  1. Le constructeur de copie est beaucoup plus facile à implémenter. Nous n'avons pas besoin d'implémenter l' interface clonable et de gérer CloneNotSupportedException .
  2. La méthode clone renvoie une référence Object générale . Par conséquent, nous devons le transtyper dans le type approprié.
  3. Nous ne pouvons pas attribuer une valeur à un champ final dans la méthode de clonage . Cependant, nous pouvons le faire dans le constructeur de copie.

4. Problèmes d'héritage

Les constructeurs de copie en Java ne peuvent pas être hérités par les sous-classes. Par conséquent, si nous essayons d'initialiser un objet enfant à partir d'une référence de classe parent, nous serons confrontés à un problème de conversion lors du clonage avec le constructeur de copie.

Pour illustrer ce problème, créons d'abord une sous-classe de Employee et son constructeur de copie:

public class Manager extends Employee { private List directReports; // ... other constructors public Manager(Manager manager) { super(manager.id, manager.name, manager.startDate); this.directReports = directReports.stream() .collect(Collectors.toList()); } } 

Ensuite, nous déclarons une variable Employee et l'instancions avec le constructeur Manager :

Employee source = new Manager(1, "Baeldung Manager", startDate, directReports);

Puisque le type de référence est Employee , nous devons le convertir en type Manager afin de pouvoir utiliser le constructeur de copie de la classe Manager :

Employee clone = new Manager((Manager) source);

Nous pouvons obtenir ClassCastException au moment de l'exécution si l'objet d'entrée n'est pas une instance de la classe Manager .

Une façon d'éviter la conversion dans le constructeur de copie consiste à créer une nouvelle méthode héritable pour les deux classes:

public class Employee { public Employee copy() { return new Employee(this); } } public class Manager extends Employee { @Override public Employee copy() { return new Manager(this); } }

Dans chaque méthode de classe, nous appelons son constructeur de copie avec l'entrée de cet objet. De cette façon, nous pouvons garantir que l'objet généré est égal à l'objet appelant:

Employee clone = source.copy();

5. Conclusion

Dans ce didacticiel, nous avons montré comment créer un constructeur de copie avec quelques exemples de code. En outre, nous avons discuté de plusieurs raisons pour lesquelles nous devrions éviter la méthode de clonage .

Le constructeur de copie a un problème de conversion lorsque nous l'utilisons pour cloner un objet de classe enfant dont le type de référence est la classe parente. Nous avons fourni une solution à ce problème.

Comme toujours, le code source du didacticiel est disponible à l'adresse over sur GitHub.