Pourquoi pas votre instruction switch type de données long, Java?
Voici un extrait de Java de Sun tutoriels:
Un switch fonctionne avec le
byte
,short
,char
, etint
types de données primitifs. Il travaille également avec des types énumérés (discuté dans les Classes et l'Héritage) et quelques classes spéciales que "wrap" de certains types de primitives:Character
,Byte
,Short
, etInteger
(discuté dans de Simples Objets de Données).
Il doit y avoir une bonne raison pour laquelle l' long
type de données primitif n'est pas autorisé. Quelqu'un sait ce que c'est?
Vous devez vous connecter pour publier un commentaire.
Je pense que dans une certaine mesure, c'était probablement une décision arbitraire basée sur l'utilisation typique de l'interrupteur.
Un commutateur peut essentiellement deux façons (ou, en principe, une combinaison): pour un petit nombre de cas, ou ceux dont les valeurs sont très dispersées, un interrupteur devient essentiellement l'équivalent d'une série de fi sur une variable temporaire (la valeur étant sous tension ne doit être évaluée une fois). Pour un nombre modéré de cas qui sont plus ou moins consécutifs de valeur, un commutateur de table est utilisée (le TABLESWITCH instruction en Java), dans lequel l'emplacement de saut est effectivement regardé dans un tableau.
L'une de ces méthodes pourrait, en principe, utiliser une valeur de type long plutôt qu'un entier. Mais je pense que c'était probablement juste une décision pratique à l'équilibre de la complexité du jeu d'instructions et le compilateur avec le besoin réel: le cas où vous avez vraiment besoin de passer un long assez rare qu'il est acceptable d'avoir à ré-écrire comme une série d'instructions if, ou autour d'une autre façon (si le long valeurs en question sont proches, vous pouvez dans votre code Java basculer l'int résultat de la soustraction de la valeur la plus faible).
Parce qu'ils n'ont pas mis en œuvre les instructions du bytecode et vous vraiment ne veux pas écrire que de nombreux cas, n'importe comment "prêt pour la production" votre code est...
[EDIT: Extrait de commentaires sur cette réponse, avec quelques ajouts sur fond]
Pour être exact, 232 est un beaucoup de cas et de tout programme avec une méthode assez long pour contenir plus que ça va être absolument horrible! Dans n'importe quelle langue. (La plus longue de la fonction je ne connais dans tout le code dans n'importe quelle langue est un peu plus de 6k SLOC – oui, c'est un gros
switch
et c'est vraiment ingérable.) Si vous êtes vraiment coincé avec le fait d'avoir unlong
où vous ne devez avoir qu'unint
ou moins, alors vous avez deux alternatives réelles.Utiliser une variante sur le thème de fonctions de hachage pour compresser le
long
dans unint
. Le plus simple, à utiliser uniquement quand vous avez le type de mal, est de les jeter! Plus utile serait de le faire:avant de passer sur le résultat. Vous aurez à travailler sur la façon de transformer le cas que vous faites des tests à l'encontre de trop. Mais vraiment, c'est toujours horrible, car il ne traite pas le problème réel de beaucoup de cas.
Une bien meilleure solution si vous travaillez avec un très grand nombre de cas est de changer votre conception à l'aide d'un
Map<Long,Runnable>
ou quelque chose de similaire à ce que vous êtes à la recherche de la façon de l'envoi d'une valeur particulière. Cela vous permet de séparer le cas dans plusieurs fichiers, ce qui est beaucoup plus facile à gérer lorsque l'affaire-comte est grande, même si elle est plus complexe à organiser l'enregistrement de l'hôte de la mise en œuvre des classes concernées (les annotations peuvent aider en vous permettant de construire le code d'enregistrement automatiquement).FWIW, je l'ai fait il y a plusieurs années (nous nous sommes mis à la nouvellement libérés J2SE 1.2 mi-chemin à travers le projet) lors de la construction d'un personnalisé du bytecode moteur de simulation massivement parallèle de matériel (non, la réutilisation de la JVM n'aurait pas été approprié en raison de la radicalement différentes de la valeur et de l'exécution des modèles concernés) et énormément simplifié le code par rapport à la grande
switch
que la version C du code était de l'utiliser.De réitérer le message, voulant
switch
sur unlong
est un signe que soit vous avez les types de mal dans votre programme ou que vous êtes en train de construire un système avec beaucoup de variation impliqué que vous devriez être à l'aide de classes. Le temps pour repenser dans les deux cas.Map<Long,Runnable>
pour résoudre le problème dans un tout autre chemin. 🙂switch
? Vouloir choisir sur un ensemble fini de beaucoup d'éléments tout simplement des points pour une erreur dans la conception fondamentale du programme. Que les gens demandent, il indique simplement que **ils ont leur conception de mal.int
fonctionnera probablement. Le mal de pirater, mais à bas prix. Vous aurez à vérifier que les événements qui se déroulent autour de ne frappez pas votre code par hasard, mais avec Guid/Uuid qui est assez rare. (Ou utiliser unMap
rempli avec anonyme intérieur des instances de classe.)int
). Aussi longtemps que vous l'utiliser comme une condition préalable pour l'égalité (c'est à dire, la valeur de l'égalité implique de hachage de l'égalité, et pas l'inverse), alors vous n'aurez pas de réels dangers.long
nombre de lignes, j'ai uniquement besoin de 4. C'est un cas de m'avoir unlong
me tendit que l'indique la ligne qui est agi, et j'ai besoin de faire des choses différentes en fonction sur la ligne qui il est. Je suppose que je pourrais cast en int, mais il aurait rendu ma vie plus facile si je pouvais avoir justeswitch
ed sur la variable. Comme il est, je suis juste en utilisant une chaîne deif
etelse if
à la place.long
ne signifie pas que vous allez vérifier toutes les possibilités, un peu comme avoir unint
ou unString
ne veut pas dire que ce soit. Cela signifie que les valeurs que vous avez, ce qui pourrait être une poignée, ont un grand gamme. Vous pourriez être vérifier quelques cas simples et de tomber dansdefault
pour le reste. Avoir à faire des changements et jette signifie que vous risquez de perdre des données. Bas de ligne, c'est un mauvais dessin Java décision de ne pas un utilisateur en question.Parce que la table de recherche de l'indice doit être de 32 bits.
switch
n'a pas besoin d'être mis en œuvre avec une table de recherche nécessairement.Une longue, dans les architectures 32 bits, est représenté par deux mots. Maintenant, imaginez ce qui pourrait arriver si, en raison de l'insuffisance de la synchronisation, l'exécution de l'instruction switch observe avec son haut de 32 bits à partir d'une écriture, et le 32 bas à partir d'un autre! Il pourrait essayer d'aller en......qui sait où! Fondamentalement, quelque part au hasard. Même si les deux écrit représenté cas valables pour l'instruction switch, leur drôle de la combinaison de probablement conduire ni à la première ni à la seconde, ou extrêmement pire, il pourrait conduire à un autre, mais sans rapport avec les cas!
Au moins avec un int (ou moins de types), peu importe à quel point vous vous trompez, l'instruction switch permettra au moins de lire une valeur qui quelqu'un a effectivement écrit, au lieu d'une valeur "out of thin air".
Bien sûr, je ne connais pas la réelle raison (ça fait plus de 15 ans, je n'ai pas fait attention que long!), mais si vous vous rendez compte à quel point dangereux et imprévisible, une telle construction pourrait être, vous serez d'accord que c'est certainement un très bonne raison de ne pas jamais ont un commutateur à longs (et tant -jeu de mots - il y aura des machines 32 bits, cette raison demeureront valides).
if
ainsi et le résultat serait tout aussi mauvais: mauvais résultat ~> mauvaise direction prise. Création d'un longif
-else
-if
chaîne au lieu d'uneswitch
entraînerait en fait exactement le même résultat.