Ah bon ?
Code:
1
2
3
4
5
6
7
8
9 try { Enum valEnum = Enum.valueOf(val); switch (valEnum) { case valEnum1: faire un truc; break; case valEnum2: faire un truc; break; } } catch (IllegalArgumentException e) { // entree invalide }
Version imprimable
Je l'utilise beaucoup en ruby (pas rails)...
C'est tres c'est tres bon CEPENDANT Il faut faire attention aux programmeurs novices qui peuvent utiliser ca n'importe comment....
Je pense que si c'est accepter, il faudra mettre des regles claires d'utilisation dans un environnement d'entreprise pour ne pas se retrouver avec un code "crado" comme certains ont dit...
Je suis assez mitige sur le point mais me laisse quand meme voter pour...
Je n'ai jamais eu de vrai probleme sur d'autres languages avec ca...
Pas contre
Je n'ai pas encore utilisé la méthode hashCode de la classe String. En attendant, je pense utiliser cette méthode
Pour.
Et je ne voies vraiment pas d'inconvénients à ça ...
Pour également la classe string est depuis le début une classe très particulière donc faire une exception de plus pour son cas ne me parait pas genant.
Si ça apporte en plus les optimisations du switch je suis pour
Je suis totalement pour un switch sur String, bien plus lisible qu'une série de if-else imbriqués. Le switch sur Enum de Java 5 ne permet pas de traiter tous les besoins. On peut souhaiter tester des radicaux de comptes comptables par exemple, sans que ceux-ci soient pour autant définis dans un Enum. Cela ne me parait pas crado. Quant à étendre le principe à tous les objets, je n'en mesure ni l'intérêt, ni les conséquences.
Je suis pour aussi il est temps de rattrapper le Cobol sur ce point !! :mouarf: Pour plus de clarté dans le code.
Il y a plein de points soulevés ici surper intéressants :
* les switchs d'intervalle : pourquoi pas, ça allège les suites de case sans fin...
* les switchs de String : là je suis moins pour ; je ne vois pas de cas où on ne peut les remplacer par autre chose (enum, introspection, injection de dépendances, fichier de conf, autres ?...)
* les switchs généralisés : là par contre, je suis entièrement contre. Si ça amuse certains de faire des switchs en pagaille, autant faire du C.
Donc je vote contre.
Je serais même partisan de créer un nouveau mot-clé à cet effet, avec les particularités suivantes par rapport au switch:
- se base sur equals, valable pour tout type d'objet non primitif
- les alternatives sont mutuellement exclusives, et ou laisse tomber la nécessité du break (d'inspiration GOTO)
Note: pour ceux que ça intéresse, la structure de contrôle "cond" en Scheme est vachement mieux pensé que le switch C-like.
Moi, je vote pour. C'est une fonction qui m'a toujours manquée et qui sera utile à plus d'un.
Cette proposition constituera une avancé pour le langage java.
Honetement avec un langage aussi dynamique pourquoi se limier aux entiers lors des structures switch
Vive la pythonisation du java
contre.
L'utilisation du type String dans un switch() devrait renvoyer une erreur: "Apprenez a utiliser les enums."
Oui, entièrement contre.
Cette discussion et le sondage sont intéressants : elle montre que beaucoup de gens préférent coder rapidement sans se soucier de la maintenance...
Moi je vote pour
une question :
En quoi cela affecterait la maintenance?Citation:
Cette discussion et le sondage sont intéressants : elle montre que beaucoup de gens préférent coder rapidement sans se soucier de la maintenance...
Typiquement une combo-box avec { "M", "Mme", "Mlle" } et le switch() qui va avec. Si tu traduis l'IHM de ton application, tu dois également traduire le code du switch() (et ne pas te tromper en recopiant :P).
Avec un Enum le problème disparait. Tu garde le meme code du switch() et tu as juste a traduire le toString() de l'Enum.
Bah oui c'est un expemple de mauvaise utilisation mais bon, si tu veux interdire avec switch, la personne fera la même chose avec une série de if, ce qui tout aussi bête.
Si tu veux interdire tout ce qui peux potentielement être mal utilisé, autant interdire le Java.
ça fait longtemps que j'attend cette possibilité et voilà enfin on va la trouver.
ç'était le bordel avec plusieurs "if".
C'est très réducteur...
Un bon langage de programmation est obligé de permettre des choses crades pour pouvoir être qualifié de langage permissif et puissant.
Ce n'est pas parce qu'on peut faire ("toto" == str) que c'est une bonne pratique (et que ça devrais être permis).
Ce n'est pas parce qu'on peut nommer une variable ($ma_variablePourrieQuiEstNomméeComme_la_super_classe) que c'est une bonne pratique (et que ça devrais être permis).
Ce n'est pas parce qu'on peut coder une classe complète sur une seule ligne que c'est une bonne pratique.
etc.
Le switch de String est un manque à cause de certains aspects particuliers des API Java et de l'historique du langage. L'introduire comblerait un manque mais il est clair que c'est aux programmeurs de se responsabiliser un minimum.
Je trouve cet ajout bien moins problématique que les alias. Un Switch de String, même crados, restera lisible et facilement corrigeable.
Que pensez-vous de ce cas ?
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 static boolean booleanFromString(String s) { switch(s) { case "true": case "yes": case "y": case "1": return true; case "false": case "no": case "n": case "0": return false; default: throw new IllegalArgumentException(s); } }
Vincent
Bonjour.
Je vois que l'argument de l'enum revient sans cesse pour descridéter cette proposition, et c'est logique en un sens.
Mais il faut se mettre à l'esprit que ce n'est pas toujours possible de passer par un enum, ou d'avoir un enum.
Par exemple, avec l'exemple de Vincent, le s qu'on teste peut être une valeur entré par l'utilisateur dans une IHM quelconque, peut aussi parvenir du parsing d'un fichier, des données récupérés d'une socket, etc. etc. etc. J'aimerais bien voir comment on peut utiliser les enums dans ces cas ...
Autre cas de figure: lorsque les éventualités sont un peu trop nombreuses pour qu'on prenne la peine de les coder sous forme d'enums ... perso, je ne m'amuserais pas à le faire avec plus d'une douzaine de valeurs possibles :aie:
Techniquement parlant c'est très simple, cf cet exemple :
http://www.developpez.net/forums/sho...8&postcount=41
Le #valueOf a ses limites par contre car si on souhaite tester une saisie qui ne respecte pas les normes de nommage des variables java comme par exemple : "pèse-personne" (le tiret '-' n'est pas accepté, l'accent est déconseillé), ou "un avion" (l'espace pose problème), ça va doubler le travail de création de l'enum.
Ca devient vraiment pénible et je comprendrais qu'on préfère coder une succession de if/else plutôt que se taper l'enum.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 enum MonEnum { PESE_PERSONNE("pèse-personne"), UN_AVION("un avion"); String str; private MonEnum(String str) { this.str = str; } public static MonEnum valueFor(String str) { for (MonEnum me : values()) { if (me.str.equals(str)) { return me; } } return null; } }
Voilou ! le valueOf est limité et ne permettrait certainement pas de faire la même chose que l'exemple de Vincent.
on pourrait surtout le faire avec des Listes...
Code:
1
2
3
4
5
6
7
8 static List<String> trueEntries = Arrays.asList("true","yes","y","1"); static List<String> falseEntries = Arrays.asList("false","no","n","0"); static boolean booleanFromString(String s) { if (trueEntries.contains(s)) return true; if (falseEntries.contains(s)) return false; throw new IllegalArgumentException(s); }
A mon avis le "switch(string)" n'est pas une solution à un problème fonctionnel.
Si vous avez des dizaines de "if (s.equals("xxxx"))" à la suite les uns des autres, la solution à votre probleme ce trouve plus dans un changement de "conception" qu'un changement de "syntaxe".
Dans ce cas précis oui, mais ca reste une solution de contournement pour un problème particulier.Citation:
on pourrait surtout le faire avec des Listes...
On perd une propriété essentielle du switch: travailler sur des constantes, de plus, le passage par une liste complique inutilement une opération triviale.
Je sais que l'optimisation n'est généralement pas la priorité des développeurs JAVA, mais ca ne fait jamais de mal.
DAns ce cas il faudrait etendre le switch() a tous les objets immutable (BigInteger, ...). Mais comment reconnaitre un immutable en Java ? (sachant qu'on peut modifier une String par reflection).Citation:
On perd une propriété essentielle du switch: travailler sur des constantes
Je ne sais pas comment sera implémenté le switch(string), mais battre une recherche dans un HashSet() ca va etre dur.
Les String ont quand même un status particulier puisqu'il peuvent être défini en tant que constante, ce qui n'est pas le cas des autres types d'objets...
Cela pourrait intégrer une sorte de hashset directement dans le bytecode...
D'ailleurs il me semble que c'est déjà fait ainsi pour les switch standard !
a++
Je ne parlais pas détendre à tous les immutables mais juste aux Strings constants, ce qui ne devrait pas poser de problèmes vu qu'ils posèdent déjà un traitement particulier en JAVA ou ils sont "inline" de la même manière que les types de base.
Après si tu modifies un String par réflexion(je ne savais pas que la réflexion authorisait ce genre de chose), c'est un détournement de l'usage normal de JAVA. Celui qui fait ça, a quand même quelques connaissances et sait qu'il faut s'attendre au pire vu que:Je serais bien curieux de voir ce que ca donne de modifier un String constant par réflexion, ca doit réserver quelques surprises.
- Le but d'une classe Immuable, c'est justement d'empecher ça.
- les Strings(et particulièrement les constants) ont droit à des traitements bien particuliers.
effectivement:
http://www.developpez.net/forums/sho...&postcount=720
En effet c'est bien le genre de surprise auquel je pensais, et il doit y en avoir bien d'autres.
C'est bizarre j'aurais cru naivement que la réflexion sur des éléments inaccessibles levait une exception. C'est quand même un sacré trou dans l'encapsulation! Même si ca me plait de savoir que l'on peut briser quelque règles de temps en temps.:evil:
c'est configurable: on en parle dans le reste de la discussion...
Ce n'est pas un trou. Pour moi "Immuable" n'est pas synonyme de "attribut privé". C'est pour ca que je suis contre un switch() sur la valeur d'un litteral String (qui n'est pas immuable) mais je suis pour un switch() sur la reference d'une instance d'un enum (qui est immuable).Citation:
C'est quand même un sacré trou dans l'encapsulation! Même si ca me plait de savoir que l'on peut briser quelque règles de temps en temps.:evil:
Il est possible de casser n'importe quelle objet ou règle d'immuabilité avec
La réflection et setAccessible(true)... et même les enums (après tout il s'agit ni plus ni moins d'un objet) :
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 class Surprise { enum MonEnum { AAA, BBB; } public static void main(String[] args) throws Exception { System.out.println(MonEnum.AAA); doEvil(); System.out.println(MonEnum.AAA); } static void doEvil() throws Exception { java.lang.reflect.Field field = Enum.class.getDeclaredField("name"); field.setAccessible(true); field.set(MonEnum.AAA, "CCC"); } }
Mais l'utilisation de setAccessible() est vraiment très limité et pas très propre lorsque c'est fait n'importe comment...
a++
Ok je viens de rejeter un coup d'oeil dans la doc en ce qui concerne la réflexion et elle est bien protégée comme il me semblait m'en souvenir. Ce qui m'avait échappé, c'est que cette protection pouvait être levée par le setAccessible(true).
Donc c'est en effet une bonne chose: on est parfaitement conscient de ce que l'on fait quand on décide d'enfreindre les règles.
Cela me renforce d'autant plus dans l'idée que celui qui utilise setAccessible(true), particulièrement pour modifier des champs non documentés, sait à quoi il s'expose. On n'a pas a se poser de question pour lui. De toule façon avec la réflexion sans contrôle, on est suceptible de faire les pires saloperies possibles avec les String, le cas du switch n'étant qu'un problème parmi d'autres.