Il est trop tard pour changer la question, mais plus précis aurait été de demander "pourquoi le clone () ne permet pas aux singletons?". Une méthode Y a-t-il une raison pour laquelle Enums en Java ne peut pas être cloné? P>
Le manuel indique que P>
Ceci garantit que les Enums ne sont jamais clonées, ce qui est nécessaire pour préserver leur statut "singleton". p>
blockQuote>
Mais le retour de l'instance elle-même préserverait également son statut et je serais en mesure de gérer les énumes associées de la même manière que d'autres objets clignables. P>
On peut soutenir que P>
L'intention générale [de clone ()] est que, pour tout objet X, l'expression:
mais pour les singletons au contraire, je veux Alors pourquoi les énumes ne sont-elles pas autorisées à être clonées ou ont-elles oublié de penser à des singletons et d'immutables, lorsque copie () code> serait plus pratique. Em> p>
x.clone ()! = x code> sera vrai, [...] p>
blockQuote>
x.clone () == x code> pour être vrai. Si l'instance elle-même serait renvoyée, le modèle singleton serait transparent pour référencer des objets. P>
clone () code> a été spécifié? P>
6 Réponses :
Je suppose qu'ils ne voulaient pas traiter des singletons comme cas spécial lorsque clone () code> a été spécifié. Cela aurait compliqué la spécification. Alors maintenant, les développeurs de la bibliothèque doivent les traiter comme cas particulier, mais pour le reste de nous, c'est bien que nous puissions faire confiance à ce
x.clone ()! = X code>. P>.
Si votre méthode de clone renvoie Le Javadoc dit: P> par convention, l'objet renvoyé par
Cette méthode devrait être indépendante de
cet objet (qui est cloné). p>
blockQuote> Enums ne sont pas censés être clonés car il est censé être supposé être un exemple de chaque valeur. P> EDIT: FORT> En réponse au commentaire suivant : P> C'est exactement ce que je critiquez. Pourquoi
ne pas renvoyer la même instance, s'il y a
ne peut pas être un autre? p>
BlockQuote> Parce que cela n'a pas vraiment de sens. Si c'est le même objet, ce n'est pas un clone. Les Javadocs disent également: P> L'intention générale est que, pour tout
objet x, l'expression:
p> L'intention est pour la méthode code> clone () code> pour renvoyer un objet distinct. Malheureusement, il est dit que ce n'est pas une exigence absolue, qui rend votre suggestion valide, mais je pense toujours que ce n'est pas sensible car il n'est pas utile d'avoir une méthode clone qui renvoie Vous n'expliquez pas vraiment pourquoi vous voulez traiter Enums comme cette instance code> plutôt qu'un objet distinct, ce n'est pas un clone, est-ce?
ce code>. Cela pourrait même causer des problèmes si vous faites quelque chose de douteux comme ayant un état mutable dans vos constantes d'enum ou de la synchroniser. Le comportement de ce code serait différent selon que la méthode du clone a fait du clonage approprié ou vient de renvoyer
ceci code>. P>
clonable code> quand ils sont intrinsèquement non claquables. Voulant avoir une méthode clone qui n'obéit pas aux conventions acceptées semble être un hack pour résoudre un problème plus fondamental avec votre approche. P> P>
Parce que le "contrat" de la méthode code> clone code> est de renvoyer une copie.
@Stephen C: Oui, mais tous les objets ne doivent pas adhérer à ce contrat, c'est-à-dire que toutes les classes ne devraient pas mettre en œuvre clonable.
Je pense que la Javadoc que vous avez citée apporte réellement le point de l'OPS: 99% de tous les programmeurs Java penseront à l'indépendance en termes d'état d'objet, c'est-à-dire que la modification de l'état du X code> n'affectera pas l'état de ( le résultat d'un précédent)
x.clone () code>. Et dans ce sens, il est très i> raisonnable d'implémenter
clone () code> par
renvoie ce code>. J'irais aussi loin que tout code s'appuyant sur la non-identité de
clone () code> résultat est beaucoup plus susceptible d'être cassé que le code qui passe immuable b> singleton b> instances à (3ème partie?) Méthodes qui tentent de
clone () code>, par exemple stocker l'état de l'objet.
Quel est le but de cloner un singleton, si Strictement parler, si vous voulez cloner quelque chose qui peut être trompeur ... P> Si vous concevez quelque chose et que vous êtes basé sur x.clone () == x code>? Vous ne pouvez pas simplement utiliser
x code> tout de suite.
x.clone () == x < / code>, le seul objet qui peut être le résultat du clone est
x code> lui-même: p>
clone () code> pour la différenciation, vous le faites malho ... p> p> p>
@Christian, votre code traite-t-il d'autres objets qui ne mettent pas en œuvre clonable ou tout faut-il être clonable?
Votre propre réponse à votre question est la meilleure. En général, les gens attendent Je pense que même s'ils pensaient à Singletons, ils ne l'auraient pas changé. Après tout, c'est la responsabilité du programmeur de décider de ce qui peut être cloné et ce qui ne peut pas, en ajoutant de manière sélective (et potentiellement remplacer) l'interface code> clonable code> et la plupart des programmeurs ne vont pas ajouter le clone () code> pour redonner un autre objet. La sémantique de
clonable code> elle-même ait plus de sens de cette façon. ("L'objet est claquant ... Oh, je dois être capable de faire des copies.") Je ne peux pas penser à une situation hors tension là où cela importe, mais c'était le sens sémantique envisagé de
clonable code> . P>
Interface classique code> sur des singletons non plus. P>
Pour des objets immuables, la seule différence entre la mise en œuvre réellement clone () code> correctement et juste
retourner ce code> est le résultat de
x.clone ()! = X Code>, que vous n'avez aucune raison réelle de se soucier de. Si vous êtes dans une situation où vous pourriez avoir un objet mutable ou immuable, faites simplement une copie réelle. Des copies d'objets immuables sont bon marché - vous n'avez pas à recueillir le graphique de l'objet, il suffit d'attribuer les champs comme les mêmes.
mais pour singletons au contraire, je veux
x.clone () == x code> être vrai. P>
Non, ce ne serait pas un clone. Donc, pour les singletons, vous voulez ceci: p>
xxx pré> blockquote>
Oui tu devrais. Un clone devrait B> renvoyer un clone qui n'a pas de sens pour un singleton.
Pourquoi voudriez-vous faire clone code> public?
Peut-être parce que ceci est la convention lorsqu'il est remplacer clone () code>, voir java.sun.com/javase/6/docs/aplon/java/lang/cloneable.html .
@ Tomhawtin-tacligne: si l'on écrit un utilitaire général pour essayer de cloner un objet, chaque champ non nul doit être connu pour identifier un objet qui ne changera jamais de quelque manière que ce soit qui affecterait le champ L'état du titulaire i> ou bien être claçable via certains moyens. Comme il n'y a pas d'autre convention standard pour identifier les types immuables, les avoir implémenter clone code> de sorte qu'il renvoie
ce code> facilite une méthode de clonage à usage général de faire ce qui devrait être fait.
@ Tomhawtin-Tackline: En outre, des singletons immuables sont souvent utilisés dans des cas où des objets mutables peuvent également être utilisés. Par exemple, code qui accepte une liste
clone code> sur n'importe quelle liste qu'il reçoit - mutable ou non -Mais ne pas avoir créé un objet redondant si la liste était mutable - semblerait le comportement le plus sensible.
mais pour singletons au contraire, je veux
x.clone () == x code> être vrai. P>
vous em> peut vouloir, mais je pense que c'est bizarre que le code suivant briserait: p>
xxx pré> (bien sûr, depuis
clone () code> ne donne que des copies peu profondes, même une implémentation correcte de celle-ci peut entraîner des erreurs dans le code ci-dessus.) p>
D'autre part, je peux en quelque sorte accepter que cela aurait un sens à Les opérations de clonage à juste
renvoient ce code> pour des objets immuables et que les Enums devraient vraiment être immuables. Maintenant, lorsque le contrat de
clone () code> a été écrit, ils n'ont apparemment pas pensé à des immutables, ou ils ne voulaient pas de cas spécial pour un concept qui n'est pas pris en charge par la langue (c.-à-d. Imutable Types). p>
et donc,
clone () code> est ce que c'est, et que vous ne pouvez pas très bien aller et changer quelque chose qui existe depuis Java 1.0. Je suis tout à fait certain que quelque part là-bas, il y a du code qui repose totalement sur
clone () code> renvoyant un nouvel objet distinct, peut-être comme une clé pour un
IdentityHashMap code>
ou quelque chose. P> < / blockquote>
Avec des énumérations, qu'est-ce qu'il y a à cloner?