98 votes

Pourquoi votre type de données d'instruction switch ne peut-il pas être long, Java?

Voici un extrait des tutoriels Java de Sun:

Un commutateur fonctionne avec les types de données primitives byte, short, char et int. Il fonctionne également avec les types énumérés (décrits dans Classes et héritage) et avec quelques classes spéciales qui "encapsulent" certains types primitifs: Caractère, Octet, Court et Entier (traité dans Objets de données simples).

Il doit exister une bonne raison pour laquelle le type de données primitif long n'est pas autorisé. Quelqu'un sait-il ce que c'est?

61voto

Neil Coffey Points 13408

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.

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).

22voto

Donal Fellows Points 56559

Parce qu'ils n'ont pas mis en œuvre les instructions du bytecode et vous vraiment ne voulez 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 l'arrière-plan]

Pour être exact, 232 est un beaucoup de cas, et un 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 un long où vous ne devez avoir qu'un int ou moins, alors vous avez deux alternatives réelles.

  1. Utiliser une variante sur le thème de fonctions de hachage pour compresser l' long en int. Le plus simple, à utiliser uniquement quand vous avez le type de mal, est de les jeter! Plus utile serait de faire:

    (int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))
    

    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.

  2. 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 big switch que la version C du code était de l'utiliser.

Réitérer le message, voulant switch sur long 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.

6voto

JRL Points 36674

Parce que l'index de la table de recherche doit être 32 bits.

-12voto

Dimitris Andreou Points 5398

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 que 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 jamais avoir un interrupteur longs (et tant -jeu de mots - il y aura des machines 32 bits, cette raison demeureront valides).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X