Question

Ceci est un exemple de copie défensive dans Effective Java.Supposons que ce scénario dans mes questions sous-jacentes nécessite une copie défensive et ne puisse pas se contenter d'un commentaire demandant au client d'éviter la mutation des objets transmis.

public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
}

Des questions:

  1. Que faire si Date je n'avais pas de constructeur pour me prendre en compte, pour me rendre plus général, un objet est passé sans mécanisme pour se répliquer, et un tel objet ne nous appartient pas, c'est-à-dire que nous ne pouvons en aucun cas le changer ?

  2. Et si le constructeur prenait le paramètre de type comme argument, disons Period(T object) et T pourrait être mutable et nécessite donc une copie défensive.Nous n’avons aucune idée de ce qu’est T.Comment faire une copie défensive dans ce cas ?

  3. Qu'est-ce qu'une interface est transmis là où certaines de ses sous-classes ont un constructeur comme Date créer un objet lui-même et certaines de ses sous-classes n'ont aucun mécanisme pour le faire ?

  4. Jusqu’où devrions-nous copier défensivement ?Disons que nous copions un tableau, mais que les éléments du tableau étaient mutables ?

Était-ce utile?

La solution

  1. Si tout son état est disponible, vous pouvez extraire son état et construire vous-même un nouvel objet.Sinon, vous ne pouvez rien y faire, sauf utiliser de mauvaises astuces de réflexion ou de sérialisation.
  2. Si T n'est pas une instance d'une classe permettant de se copier, vous ne pouvez rien faire.
  3. Vous ne pouvez rien y faire.
  4. Ça dépend.

En lisant votre question, il semble que vous souhaitiez appliquer partout les conseils de « copie défensive ».Vous ne devriez pas.La plupart du temps, le code utilisant des objets mutables souhaite une référence à l'objet d'origine, et non une copie.Surtout si ce que vous obtenez comme argument est une instance d’une classe ou d’une interface abstraite.

Vous êtes obligé de faire une copie défensive de Date car il s'agit d'un type de valeur mutable qui ne devrait pas être mutable et ne le serait pas s'il avait été correctement conçu.Si vous favorisez l’immuabilité des types valeur, les copies défensives deviennent inutiles.Pour les types sans valeur, vous ne souhaitez généralement pas une copie, mais une référence à l'objet.

Autres conseils

  1. Si vous ne pouvez de toute façon pas changer l’état de l’objet, vous n’avez pas besoin d’une copie défensive.
  2. La seule chose que vous pouvez faire est de supposer une implémentation probable de T et de la vérifier avec exemple de.
  3. Pareil que 2.
  4. À votre discrétion.Si vous supposez que la modification des éléments du tableau pourrait interrompre votre programme à un autre endroit, vous devez également tous les copier.

La programmation défensive est importante lorsque les objets que vous transmettez à une méthode sont mutables.Une bonne pratique (également décrite dans le livre Effective Java) consiste à les rendre immuables.

  1. Si la classe Date n’est pas finale, vous pouvez écrire une classe wrapper pour elle, c’est-à-dire une sous-classe de Date.
  2. Ça dépend.Il ne sera probablement pas nécessaire de le cloner.
  3. Cela ne devrait pas vous déranger.L'implémenteur d'une interface doit s'occuper des problèmes de synchronisation.Généralement, c'est une bonne pratique de transmettre les interfaces au lieu de leurs implémentations.
  4. Pour les collections Java standard, il existe de nombreuses méthodes utilitaires dans la classe java.util.Collections, telles que unmodifiableList et unmodifiableMap, destinées à être utilisées pour la programmation défensive.
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top