Lorsque je commençais à programmer en Java, le fait que les instructions switch ne prennent pas de chaînes me frustrait. Ensuite, en utilisant Enums, j'ai réalisé les avantages que vous obtenez avec eux plutôt que de transmettre des valeurs brutes - la sécurité du type (qui facilite la refactorisation) et la clarté pour les autres développeurs.
J'ai du mal à penser à une situation où avec SE7 je vais maintenant décider d'utiliser un commutateur avec des chaînes comme entrées plutôt que Enums. S'ils sont implémentés via la commutation de chaînes entières (par exemple plutôt que des correspondances partielles ou regex), il ne semble pas offrir moins de raisons pour que le code change.
Et avec les outils IDE et le rapport lecture / écriture du codage, je serais beaucoup plus heureux de générer automatiquement une énumération supplémentaire que de passer des valeurs de chaîne.
Quel avantage nous apportent-ils en tant que programmeurs? Moins de plaque de chaudière?
Il ne semble pas que la langue criait pour cette fonctionnalité. Bien qu'il y ait peut-être un cas d'utilisation que j'écarte.
la source
Réponses:
Pour autant que je sache, la question est de savoir pourquoi l'encapsulation des constantes String dans enum n'a pas été considérée comme suffisante pour couvrir les besoins des utilisateurs de langue. Cela a été résolu dans la proposition de fonctionnalité officielle annoncée sur la liste de diffusion JDK 7 (projet Coin).
D'après ma lecture de la proposition, l'alternative à l'utilisation d'énumérations a été rejetée au motif qu'elle introduit des types de ballonnement. Pour votre commodité, la partie pertinente de la proposition est citée ci-dessous, la déclaration concernant les énumérations étant indiquée en gras :
la source
En plus de rendre le code plus lisible, il existe des gains de performances potentiels par rapport aux
if/else if
comparaisons. La pertinence du changement dépend du nombre de comparaisons que vous feriez. Un interrupteur de chaîne sera émis sous la forme de deux instructions de commutation distinctes. Le premier fonctionne sur des codes de hachage, il a donc tendance à être unlookupswitch
, ce qui donne finalement laO(log n)
complexité. Le second est toujours parfaitO(1)
tableswitch
, donc la complexité combinée est toujoursO(log n)
. Une chaîne unique et linéaire deif/else if
déclarations donnerait uneO(n)
complexité légèrement pire .Si vous comparez plus de, disons, trois chaînes, alors a
switch
est probablement plus lisible et compact. Il fonctionnera probablement mieux, bien que vous ne remarquiez probablement pas de différence, sauf si vous effectuez un grand nombre de comparaisons sur un chemin de code à chaud.la source
if/else
bloc comme une mauvaise pratique, mais pour le moment, je n'aurais pas beaucoup de raisons d'en utiliser un.Le changement de chaîne peut être utilisé lorsque vos
enum
valeurs proviennent de l'extérieur, c'est-à-dire stockées dans une base de données.Une autre chose notable dans JDK 7
switch
est qu'il est beaucoup plus performant que lesif-else
constructions.Et un bon cas d'utilisation pour des chaînes rapides
switch
peut être l'analyse de flux JSON / XML lorsque vous devez effectuer de nombreux commutateurs sur les types de nœuds et d'attributs. Je ne peux pas penser à une meilleure option pour cela.la source
enum
s peut être utilisé dans ce cas en raison de la nature statique de Java. Quand j'écrivais ceci, je pensais à uneRole
bibliothèque de sécurité qui est généralement fournie en classe et ne peut pas être inséréeenum
. Un autre cas est un code Java / Groovy compilé dynamiquement - dans cette situation, qui est cependant rare, les commutateurs de chaîne peuvent être une meilleure option.Simplicité
La prise en charge des chaînes dans Switch est utile pour traiter les données sans conversion en énumération ou
if-else
logique. Il est parfois plus simple d'activer String.De la proposition de fonctionnalité à la liste de diffusion JDK 7 (Project Coin) ( @gnat answer )
Version If-Else
C'est court, mais beaucoup
if's
sont difficiles à lire. Et c'est lent.Version énumérée
Les énumérations doivent être définies, c'est bien, mais parfois pas nécessaire.
Traitement comme d'habitude
JDK 7 - Strings in switch Statements version
Nous pouvons traiter sans convertir ni définir de types supplémentaires.
la source
La plupart des améliorations dans n'importe quelle langue visent à rendre le code plus facile à lire. Je préfère le code lisible à la fantaisie tous les jours.
Vous ne le croyez peut-être pas, mais essayez:
la source
Les énumérations sont excellentes et vous devez les utiliser à la place des chaînes lorsque vous en avez la possibilité. Mais il y a des moments où vous ne pouvez tout simplement pas, par exemple lorsque vous devez travailler avec un objet externe venant de l'extérieur de Java. Imaginez que vous devez analyser quelque chose. Comme la réponse du serveur, la configuration, le fichier journal ou quelque chose de similaire: vous avez un tas d'options que vous recherchez et il n'y a aucun moyen de les énumérer. Donc, en Java <7, vous seriez coincé avec un tas de
Vous pouvez toujours utiliser des énumérations dans ce cas en essayant simplement de les obtenir par des noms et / ou en fournissant une routine String-> Enum personnalisée, mais parfois ce n'est pas possible ou tout simplement pas pratique (c'est-à-dire lorsque vous devez créer trop d'énumérations)
TLDR : vous devez absolument utiliser Enums lorsque vous travaillez uniquement avec du code Java mais ce n'est pas toujours possible avec des objets externes. J'espère que mon explication a du sens.
la source
if
instructions, vous devriez quand même les résumer , ce qui signifie que vous pouvez toujours utiliser des énumérations ou un modèle de commande, etc.Je ne suis pas d'accord avec l'opinion qu'il s'agit d'un code plus propre et lisible lorsque vous l'utilisez
Strings
dans des instructions switch et pensez que c'est une mauvaise pratique de programmation. Si vous changez la valeur que vous utilisez pour stocker, vous devez la changer à chaque changement ou à toute occurrence if-elseif. Ce n'est pas bon car vous mettez des valeurs codées en dur à chaque bir de votre code. Qu'allez-vous faire si un jour vous décidez de modifier l'une de ces valeurs codées en dur? Rechercher et remplacer chaque copie de celui-ci?Si vous avez des valeurs codées en dur que vous faites des instructions if-elseif, l'utilisation de valeurs primitives constantes pour elles est bien meilleure avant Java 1.5 simplement parce qu'elle apporte une sécurité de type.
OK, il y aura des situations où vous obtiendrez des valeurs de chaîne (à partir de la requête HTTP, des fichiers, etc.) et les convertir en valeurs primitives est un problème. Mais
Enum
je fais du bon travail à ce stade. Parce que lorsque vous souhaitez modifier la valeur que vous stockez dans Enum, changez-la simplement lorsque vous déclarez. Il n'est pas nécessaire de changer quoi que ce soit d'autre dans votre code. (Vous devez bien sûr modifier les valeurs stockées ailleurs).Bien sûr, si vous implémentez simplement un code sale et paresseux, c'est parfait. Vous ne voulez pas impliquer de coder beaucoup de
Enum
s, mais dans un logiciel complexe à grande échelle qui vous tuera.la source
Si vous savez quelles informations arrivent et qu'elles ne peuvent être que de 5 états, utilisez un
Enum
. Cependant, si les états possibles peuvent être supérieurs à 9000 et que vous n'en avez besoin que de 42, il est préférable d'utiliser un commutateur car vous ne voulez pas taper tous ces états.Un Enum a tendance à être le choix de la plupart dans la plupart des circonstances, sauf lorsque les états possibles sont inconnus ou qu'il y en a beaucoup et que vous ne vous souciez que de quelques-uns.
Mais pourquoi l'ont-ils introduit maintenant? C'était juste un changement qui permettait un code plus propre.
Dans 1.5, ils vous permettaient également de créer des corps personnalisés pour Enums.
la source
default
dansswitch
entre en jeu. Je ne sais pas que vous pouvez avoir un état par défaut avecEnum
, à moins que vous ne fassiez un état par défaut, mais ce code est tout simplement gonflé alors que aswitch
est beaucoup plus propre à utiliser.UNKNOWN
état sur un Enum est gonflé, mais pas undefault
boîtier sur un commutateur.