42 votes

Pourquoi les gens ont-ils si peur d'utiliser clone() (sur les collections et les classes JDK) ?

A plusieurs reprises, j'ai soutenu qu'utiliser clone() n'est pas une si mauvaise pratique. Oui, je connais les arguments. Bloch a déclaré c'est mauvais. Il l'a fait en effet, mais il a dit que mettre en œuvre clone() est mauvais. En revanche, l'utilisation du clone, surtout s'il est mis en œuvre correctement par une bibliothèque de confiance, telle que le JDK, est acceptable.

Hier encore, j'ai eu une discussion sur une de mes réponses qui suggère simplement que l'utilisation clone() para ArrayList est OK (et n'a pas reçu de votes positifs pour cette raison, je suppose).

Si nous regardons le @author de ArrayList nous pouvons voir un nom familier - Josh Bloch. Donc clone() en ArrayList (et d'autres collections) est parfaitement acceptable (il suffit de regarder leurs implémentations).

Il en va de même pour Calendar et peut-être la plupart des java.lang y java.util classes.

Alors, donnez-moi une raison pourquoi ne pas utiliser clone() avec les classes du JDK ?

22voto

Tom Hawtin - tackline Points 82671

Alors, donnez-moi une raison de ne pas utiliser clone() avec les classes du JDK ?

  • Étant donné un ArrayList vous auriez besoin d'une référence getClass pour vérifier qu'il ne s'agit pas d'une sous-classe de la classe JDK. Et ensuite ? On ne peut pas faire confiance aux sous-classes potentielles. On peut supposer qu'une sous-classe aurait un comportement différent d'une manière ou d'une autre.
  • Il faut que la référence soit plus précise que List . Certaines personnes n'y voient pas d'inconvénient, mais l'opinion majoritaire est que c'est une mauvaise idée.
  • Tu devras faire face à un lancer, un lancer dangereux en plus.

9voto

SiLent SoNG Points 1510

D'après mon expérience, le problème de clone() se pose sur les classes dérivées.

Dites, ArrayList implémente clone(), qui renvoie un objet de type ArrayList .

Supposons que ArrayList a une classe dérivée, à savoir, MyArrayList . Ce sera un désastre si MyArrayList ne surcharge pas la méthode clone(). (Par défaut, il hérite du code de ArrayList ).

L'utilisateur de MyArrayList On peut s'attendre à ce que clone() renvoie un objet de type MyArrayList Cependant, ce n'est pas vrai.

C'est ennuyeux : si une classe de base implémente clone(), sa classe dérivée doit surcharger clone() jusqu'au bout.

7voto

polygenelubricants Points 136838

Je répondrai par une citation de l'homme lui-même ( Josh Bloch on Design - Constructeur de copie ou clonage ? ) :

Il y a très peu de choses pour lesquelles j'utilise Cloneable plus. Je fournis souvent un public clone sur les classes concrètes parce que les gens s'y attendent.

Ça ne peut pas être plus explicite que ça : clone() sur les classes de son cadre de collecte sont fournies parce que les gens l'attendent . Si les gens n'en attendaient plus, il l'aurait volontiers jeté. Une façon d'amener les gens à ne plus l'attendre est d'éduquer les gens à ne plus l'utiliser, et non de préconiser son utilisation.

Bien sûr, Bloch lui-même a également dit (ce n'est pas la citation exacte mais elle est proche) "L'API, c'est comme le sexe : faites une erreur et vous la subissez à vie". Tout public clone() ne pourra probablement jamais être repris. Néanmoins, ce n'est pas une raison suffisante pour l'utiliser.

6voto

Daniel Points 3893

Afin de ne pas encourager d'autres développeurs, moins expérimentés, à mettre en œuvre le programme Clone() eux-mêmes. J'ai travaillé avec de nombreux développeurs dont le style de codage est largement copié sur du code (parfois horrible) avec lequel ils ont travaillé.

3voto

Darin Dimitrov Points 528142

Il n'impose pas si l'implémenteur fera une copie profonde ou superficielle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X