Il me semble que non. Certaines opérations [comme par exemple le for (Personne Pers : _lPers)] ne fonctionnent que sur des objets de collections.
Version imprimable
ce qui est dérangeant dans cette proposition est la distance qu'il y a entre la construction switch et un objet…
à la base, switch compare avec "==" pour choisir la branche…
mais pour String on supposerait utiliser equals() parce que c'est ce qui a un sens…
on passe donc d'une construction basée sur un opérateur intrinsèque à un appel de méthode…
ce n'est pas du même ordre et c'est gênant…
(ce qui n'est pas le cas d'un tableau de type char, int, … d'où l'idée de proposer l'extension du switch aux tableaux… et pas seulement de char… - et ce n'est évidemment pas pour régler le cas de Straße et Strasse…)
que l'on désire l'élégance du switch pour travailler avec des objets et en particulier ici des String est une chose, utiliser la même syntaxe en est une autre…
je préférerais voir une proposition qui offrirait une autre syntaxe pour les switch sur des objets et irait plus loin, dans le sens du "case" en Ruby par exemple, où l'on peut utiliser des regexp dans les conditions…
Je comprends le point de vue, mais bon, dans un switch, on ne voit nulle part l'opérateur qui a été utilisé pour le test...
Donc, pourquoi ne pas utiliser switch, au moins on se doute de ce qu'il fait.
Ca fait franchement beaucoup de discussions pour pas grand chose...
Comme dans toutes les propositions de modification de syntaxe, on prend ou on ne prend pas...
Le switch existe plus ou moins dans cette forme ou dans une autre dans quasiment tous les langages et je ne pense pas que, pour cette raison, ces autres langages devienennt tout d'un coup moins bons.
C'est un moyen de simplifier des liste de if-else, mais ce n'est pas une raison pour en mettre 50 à la suite.
Pour parce que je ne vois pas pourquoi je serais contre... et parce qu'à chaque fois que j'ai dû m'en passer, ça m'a manqué!
Cette question a probablement été déjà posée mais je n'ai pas le courage de me taper les 9 pages de posts :D :
pourquoi juste les strings? Pourquoi ne pas étendre le switch à tous les objet via la méthode equals()? Cela aurait même du être le mode de fonctionnement depuis le début puisque ça fonctionne aussi bien avec les types primitifs (depuis l'autoboxing, mais même avant rien n'empêchait un mode de fonctionnement différent si on désignait un type primitif, on programme pas en statiquement typé pour rien) qu'avec les strings, les dates, et de manière générale tout ce qu'on peut imaginer.
A la rigueur en y réfléchissant bien c'est peut-être même avec les strings que c'est le moins utile, car il existe plusieurs façons de les comparer (avec ou sans trim()? case sensitive ou insensitive? en ignorant les caractères accentués ou pas?). J'ai bien peur que même en disposant de ce switch on ne doive parfois se résoudre à faire un bon vieux if/else/if parce qu'on doit tuner la comparaison.
je trouves que le switch case devrait être étendu à bcp plus qu'au String (Enumérations, ...). J'ai jamais compris pq c'était si limitatif..
il n'y a pas que les enums... pourquoi n'importe quel objet pourrait ne pas être evalué dans un switch case. Certains vont dire que c'est pas "joli", certes mais ca rend le switch case quasiment inutile (pour ma part je ne l'utilise jamais de fait cette énorme limitation).
Je suis pas un adepte des switch case, mais à certains moments ils serait bien pratiques pour remplacer des if else if assez longs... Et ce n'est pas toujours faisable de passer outre...
Apparement il y a de grande chance que ce soit implémenté , cf ici(90%)
J'en ai déjà parlé cela poserait problèmes pour plusieurs raisons :
- L'état d'un objet peut varier, et a.equals(b) peut être vrai à un moment donné et faux un peu plus tard si l'objet n'est pas immuable.
- L'appel à la méthode equals() peut nécessiter une synchronisation, car rien ne garantie qu'elle soit thread-safe.
- Le compilateur ne peut pas connaitre les valeurs des objets (puisqu'ils dépendent de l'exécution) et ne peut donc pas vérifier la cohérence du switch ni l'optimiser.
:arrow: Tous ces problèmes ne sont pas vrai pour les Strings et les enums qui sont des objets bien spécifique (même si les enums ne sont pas totalement immuable, leurs conditions d'égalité ne peut pas être redéfini).
Dans ce cas les enums serait plus adapté... ou alors il faut utiliser une Map !Citation:
Je suis pas un adepte des switch case, mais à certains moments ils serait bien pratiques pour remplacer des if else if assez longs... Et ce n'est pas toujours faisable de passer outre...
a++
Totalement pour... inutile de commenter... ;)
1.Donc si je comprends bien je dois virer tous mes if/else if là je fait un a.equals(b) sous prétexte que mes objets varient... La synchro, faut la gérér là où il faut, c'est pas ton switch ou if / else if qui y changera quelque chose. Sinon selon ta théorie il ne faut surtout plus faire une test d'égalité à quelque niveau que ce soit ... switch ou if/else if
un codeaurait les mêmes problèmes de ce que tu sites --> faut-il interdir les if pour autant. Ces pour ça qu'il existe les méthodes/blocs synchronisés, à toi de gérer...Code:
1
2
3
4
5 if(a.equals(b)){ } else if (a.equals(c)){ }
2.je REdit, il n'y a pas que les strings ... ça pourrait. être intéressant dans d'autre cas
3.dernièrement puisqu'on part sur le sujet de la synchronisation qu'est-ce qui me garanti l'(in)égalité avec les numériques primitifs dans un switch en mulitthread? ou même avec une énumération ?
sa sera bien pratique cool :king:
hmmm hmmm, oui les éléments d'une énum sont immutable... mais qu'est qui me fait dire que l'objet que je teste est toujours le même au sein de mon swich... même chose avec les primitifs :roll:
Nous donnesCode:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 public class Main implements Runnable { private Color color; public Main(Color color){ this.color = color; } public void setValeur(Color color){ this.color = color; } /** * @param args the command line arguments */ public static void main(String[] args) throws Exception { Main main = new Main(Color.BLUE); Thread th = new Thread(main); th.start(); Thread.sleep(1000); main.setValeur(Color.RED); } public void run() { try{ switch(color){ case BLUE : System.out.println("case 1"); System.out.println(color); Thread.sleep(5000); System.out.println(color); break; case RED : System.out.println("case 2"); System.out.println(color); Thread.sleep(5000); System.out.println(color); break; } } catch(Exception e){ } } public enum Color{ RED,BLUE,YELLOW; } }
Résultat idem avec un int ou autre...Code:
1
2
3
4 case 1 BLUE RED
Donc les problèmes de synchro est un faux débat car elle doit être gérée avec les blocs/methodes synchro. Les blocs switch ne sont pas synchronisés...
:mrgreen:
Bien sur la variable d'entrée peut être modifiée a tout moment, mais c'est sa valeur au moment précis de l'évaluation de la fonction "switch(x)" qui fait foi.
ce qui doit être immutable ce sont les valeurs de comparaison (les "case" du switch) pour savoir quel bloc de code il faut executer. Sinon, le switch() ne serait pas l'équivalent de:
Code:
1
2
3
4
5
6
7
8 if (variable.equals(case1)) { // ... case 1 } else if (variable.equals(case2)) { // ... case 2 } else { // ... default }
mais plutot de:
Code:
1
2
3
4
5
6
7
8
9
10 if (variable.equals(case1)) { // ... } if (variable.equals(case2)) { // ... } if (!variable.equals(case1) && !variable.equals(case2)) { // ... }
Dans un switch tu ne peux utiliser que des constantes, et il est donc impossible de modifier leur valeur. Ainsi le code suivant est correct :
:arrow: Tu peux faire tout ce que tu veux entre la déclaration des constantes et le switch tu ne pourras pas modifier leurs valeurs.Code:
1
2
3
4
5
6
7
8
9 final int A = 10; final int B = 20; // ... switch (x) { case A: System.out.println("A"); break; case B: System.out.println("B"); break; }
Avec des String on se retrouverait dans le même cas :
:arrow: Il faut noter que les String sont déjà considéré à part par le compilateur/JVM et que c'est le seul "objet" que l'on peut utilisé comme constante (voir : Qu'est-ce qu'une constante ?).Code:
1
2
3
4
5
6
7
8
9 final String A = "10"; final String B = "20"; // ... switch (x) { case A: System.out.println("A"); break; case B: System.out.println("B"); break; }
Avec des object muable cela n'est plus vrai, par exemple avec des StringBuffer
:arrow: On a modifié la valeur de B et le switch possède désormais deux cases identiques !Code:
1
2
3
4
5
6
7
8
9 final StringBuffer A = new StringBuffer("10"); final StringBuffer B = new StringBuffer("20"); B.setCharAt(0, '1'); switch (x) { case A: System.out.println("A"); break; case B: System.out.println("B"); break; }
a++
A voté "Pour", car les langages comme Java/.Net/Delphi sont fait pour développer rapidement et de façon un peu crado.
Amusant comme remarque .. java fait pour programmer crado, surprenant quand on voit le soin apporté dés la conception du langage à éviter les choses potentiellement dangereuses découverte avec d'autres langages comme le C++
Etonnant aussi quand on voit le nombre d'API matures et efficace qui ont vues le jour en Java et qui commence à être portée vers d'autres langages.
Juste pour ma culture personnelle, pour toi quel serait le ou les langages destinés à programmer proprement et efficacement ?
Bulbo ;)
Je voulais dire que ces langages sont plutôt fait pour coder rapidement. Fatalement le code est un moins réfléchi. Le c++ si tu t'amuse à coder aussi vite que java ou autres, bein ton code sera pas très jolie. Je passe 7h par jour sur du delphi, ( oui oui ici on parle java ) et 5h par jour sur du c++ ( pour moi c++ permet de faire des oeuvres d'art performante c'est mon avi . ) Mais c'est pour dire que quand on choisi du c++ c'est qu'on a le temps de réfléchir à ce qu'on fait, si on prend du java, delphi ou .Net c'est pour allé vite. Mais ne remettons pas la discution java c++ ici.
Juste que un peu de sucre syntaxique ça aidera à coder plus vite. Et que si c'est moins jolie bein c'est pas trop grave .
EDIT: J'ai corrigé un peu mon msg plus haut, c'est qu'il tombait un peu comme un cheveux sur la soupe :p. ( si j'ai sorti le mot crado c'était en référence aux messages du début du sujet ).
Sans vouloir retomber dans l'éternelle discussion java vs c++, juste pour te donner un autre éclairage:
En C++ si tu veux aller vite tu peux, les casts barbare, les accès pirate, les macros de brute, tout ça ce sont des 'raccourcis' que j'ai déjà pas mal vus dans les code C++ que j'ai rencontré dans mon travail. Heureusement C++ permet de faire aussi du travail propre comme tu le dis, mais pas seulement et seul la personne compétente et motivée le fera.
En Java tu n'as pas le choix, tu codes pur objet et en respectant les règles, le résultat est un code plus propre et pas forcément plus rapide à écrire. Ce qui donne l'impression que c'est un langage permettant d'écrire rapidement des programmes c'est qu'il vient avec une grosse API de base et qu'il y a énormément de framework puissant autour qui permettent de faire énormément de choses.
Quand tu regardes certains patterns par exemple, le java est vraiment plus lourd à manipuler, regarde le visiteur par exemple .. 10x plus simple en C++.
Moi actuellement j'utilise java pour un projet ou en lieu et place il y a une dizaine d'année tout le monde aurait mis du C++, pire je suis en train de me débarrasser des dernières parties écrites en C++ car en terme de maintenance et d'évolution elles sont vraiment pénalisantes pour le reste de notre projet.
Et c'est d'ailleurs pourquoi certains sucre syntaxique m'horripile autant..
En espérant ne pas démarrer un troll ici,
Bulbo ;)
Je suis pour à 100% ! :mouarf:
Je trouve "naturel" de faire des switchs sur des String.
Pour, mais avant faire ce modification, il faut que ils finalement ajoutent l'operateur == pour String.
Ca par contre c'est impossible car même si String est un objet avec de caractéristiques spéciales(constantes, opération +, ...), il reste un objet et la comparaison entre objets signifie une comparaison de la référence.
Par contre je me demande s'il ne serait pas judicieux d'ajouter un type primitif string. C'est juste une idée comme, ça je n'ai pas plus que ça réfléchi aux éventuelles conséquences.
Oui, un type primitif string peut etre une bonne idee - il y a un type string dans C# et ca marche parfaitement. Mais ce n'est pas un type vraiment primitif, et c'est pour ca qu'ils n'avons pas l'ajoute dans Java. Et ils ne l'ajouteront pas, probablement.
En general, je pense qu'il y a quelque chose sans tete avec toutes ces comparaisons:
mais:Code:
1
2
3 5==5 => true, bien sur new Integer(5)==5 => true new Integer(5)==new Integer(5) => false
Avec ce savoir, on peut ecrire switch(new Integer(5)){case 5:...} et ca va marcher. Ca signifie que Java peut comparer references une fois, et valence une autre fois. Alors, maintenant je pense que c'est possible qu'ils ajoutent switch pour String sans changer comparaison des Strings.Code:
1
2 new Integer(5).equals(5) => true new Integer(5).equals(new Integer(5)) => true
(Excusez moi pour mon francais pauvre et pour mon manque d'accents, mais je ne suis pas francais. Merci.)
Non en fait c'est tout à fait logique. A partir du moment ou tu as une classe c'est une comparaison des références et non des valeurs.
Le cas de la comparaison Interger/int(et donc du switch) est particulier, d'ailleurs avant Java 1.4, ça te donnerait une erreur. C'est juste que grâce à l'autoboxing apparu avec Java 1.5, Integer est automatiquement converti en int. Donc la comparaison ce fait par valeur entre entre deux int.
Il y a aussi un autre chemin pour faire comparaison des Strings possible. Je pense qu'ils pourraient changer de comparaison emploie quand on utilise switch. Maintenant le comparaison emploie par switch est ==, mais il pourrait etre .equals(). Ca ferait les deux codes faire la meme chose:
Code:
1
2
3
4
5 switch(obj1) { case obj2: ... }
Avec ca, ils devrait permettre obj2 a ne pas etre const, et aussi ca aurait besoin de l'autoboxing du obj1 s'il est un type primitif. On de devrait changer l'ancien code, mais on peut comparer Strings et autres objets avec switch sans acun probleme.Code:
1
2 if(obj1.equals(obj2)) ...
J'ai longtemps hésité entre pour et contre.
J'ai finalement voté pour. Apres tout pour des classes de tests ça me serait bien utile. Mais je penses pas l'utiliser des mes développements finaux. Enfin je dis ça mais au boulot on est encore à la java 1.4.2, ....
JHelp
Perso je vote contre... les enumérations remplacent avantageusement ce genre d'opération.
Pour moi, du jour ou on fait un 'switch()' c'est qu'on a une liste de valeurs énumérées... et donc on utilise un enum.
Code:
1
2
3
4
5 public enum Booleans { True, False };
Contre aussi, il y a certainement des cas légitimes de faire de la comparaison de chaines en dur mais je reste convaincu qu'ils sont rares.
De façon générale les chaines de caractères ne devraient qu'exceptionnellement être dans le code. Si ce sont des éléments de langue 'Mr' 'Mme' 'Mlle' 'True' 'False': ils devraient être dans des fichiers de config pour anticiper la localisation ou permettre le parametrage par un non-développeur.
Les chaines de caractères ne devraient pas servir de marqueur interne, les énum sont là pour ça.
Reste les cas genre lecture de xml, communication diverses avec d'autres entités. Mais là encore on va vite se trouver avoir un niveau d'abstraction qui fera que les chaines à comparer ne seront pas statiques mais dans une variable.
Par contre le switch sur le chaines risque d'amener et d'encourager des pratiques peu recommandables:
-utilisation de chaines au lieu d'enum: c'est lourd et ca ne sert à rien.
-comparaison d'objet en passant par des strings:
ou pireCode:
1
2
3
4
5
6
7
8
9
10
11 MonObjet obj=...; swith(obj.toString()){ case "toto": // break; case "titi"; }
Je trouve le bénéfice-risque très limité.Code:
1
2
3
4
5
6
7
8
9
10
11 swith(obj.getClass()){ case "MonObjet": // break; case "MonAutreObjet"; }
pour moi ça me faire qlq chose qui bien et donc je vote pour.
Dur de se prononcer sur cette proposition.
Le type String est très particulier, si je me souviens bien quand on fait :
on a le même objet dans la Heap (désolée, je ne connais pas la traduction) spécial String, donc les deux sont les même => le résultat est "true" pour equals et potentiellement pour ==.Code:
1
2
3
4 String s1 = "Test"; String s2 = "Test"; System.out.println(s1.equals(s2)); System.out.println(s1 == s2);
Donc le type String est en effet approprié au switch.
Mais ça reste un Objet, et utiliser un objet dans les switch case, je suis totalement contre, les enum suffisent, java n'est pas php.
Vouloir intéresser du monde à java en laissant le développeur faire tout est n'importe quoi n'est pas une bonne idée, il suffit de voir le code php auquel on a affaire souvent. Je n'ai rien contre le php, mais les vrais développeur php sont rare, le php restant LE langage de bidouille pour ceux qui ne savent pas programmer. C'est bien, c'est utile, c'est un langage rapide, mais je doute que ce soit la finalité de java.
Clair, ça manque.
Attention c'est un cas particulier liée aux String compilées (les constantes), on peut éventuellement passer par un String.intern() si la String a été créée en cours de programme (saisie, transfert rmi...) pour obtenir le même résultat. Mais le mieux est en général d'utiliser un equals sur les String comme sur tous les objets.
Exemple, le code suivant est faux
Je suis d'accord avec toi sur le fait qu'un switch ne doit à priori pas s'appliquer à des objets.Code:
1
2
3
4
5
6
7
8 System.out.println("Votre nom:") String nom = lectureClavier(); if(nom=="bill"){ // unreachable code System.exit(0); } //(mais je n'ai rien contre bill en particulier)
Pour!
Cela sonnerait enfin le glas des longues séquences de if ... else if ... D'autre part, je serais même d'accord avec le fait que les opérateurs de comparaison soient surchargés pour String. Il y a en effet peu d'intérêt à comparer des chaînes de caractères par référence. Et le cas échéant Sun n'a qu'à proposer un nouveau moyen de comparer des objets en étant sûr que la comparaison se fasse par référence (un opérateur is ou une méthode statique Object.referenceEquals(Object, Object)). Pour finir, je dirais même (même si c'est un autre débat) qu'il serait temps que Sun réfléchisse à un moyen d'introduire la surcharge d'opérateurs dans Java. Je n'ai vraiment jamais perçu son omission comme un avantage (essayez de faire des calculs sur BigDecimal pour vous en convaincre).
Faire un switch sur une chaine de caractère cela revient comparer cette chaine à un nombre fini de modalités existantes. En effet les expressions de case doivent correspondre à des expressions constantes.
Ces modalités seront donc soit :
- Écrites en dur dans le switch (dans le pire des cas)
- Déclarées comme constantes statiques ailleurs dans le code (dans le meilleur des cas)
Dans les deux cas il vaut mieux utiliser une énumération. Et ça tombe bien : on peut déjà faire un switch sur une énumération.
Donc je suis contre cette proposition et pour une utilisation plus fréquente des énumérations.
Sauf que l'enum n'est pas exactement équivalent à une constante statique. D'ailleurs elles ne sont utilisées nulle part dans l'API Java. Pas même pour les classe post Java 5.0 il me semble.Citation:
Dans les deux cas il vaut mieux utiliser une énumération. Et ça tombe bien : on peut déjà faire un switch sur une énumération.
Donc je suis contre cette proposition et pour une utilisation plus fréquente des énumérations.
+1
Une enum représente un nombre d'élément fini.
Or on peut avoir besoin de faire un switch sur certain valeurs, et un cas générique pour toutes les autres valeurs... qui pourrait être infini !
Les enums ne sont pas vraiment adapté à cela !
De plus, je trouve que faire une enum uniquement pour simuler un switch sur les String est en quelque sorte un aveu que le switch sur les String est manquant ;)
Elles sont bien utilisées dans Java 5.0/6 (Thread.State, Desktop.Action, TrayIcon.MessageType, ...) mais pas dans la grande majorité des classes mais c'est surtout pour une raison de compatibilité ascendante...
Contrairement aux Generics qui permettaient d'adapter les classes existantes en conservant la compatibilité, l'utilisation des Enums ne peut pas remplacer l'utilisation des constantes car cela casserait la compatibilité...
a++
Cette évolution me semble inutile surtout parce qu'il n'est pas possible de l'utiliser en ignorant la casse ou avec trim() ou des expressions régulières.
L'étendre à toutes les classes est impensable.
L'utilisation des enums est bien suffisante est plus facile à faire évoluer.