Ich denke, bis zu einem gewissen Grad war es wahrscheinlich eine willkürliche Entscheidung, die auf der typischen Verwendung von Schaltern beruhte.
Ein Schalter kann im Wesentlichen auf zwei Arten implementiert werden (oder im Prinzip als Kombination): Für eine kleine Anzahl von Fällen oder solche, deren Werte weit verteilt sind, wird ein Schalter im Wesentlichen das Äquivalent einer Reihe von ifs auf einer temporären Variablen (der Der eingeschaltete Wert darf nur einmal ausgewertet werden. Für eine moderate Anzahl von Fällen, deren Wert mehr oder weniger aufeinanderfolgend ist, wird eine Switch-Tabelle verwendet (die Anweisung TABLESWITCH in Java), wobei der Ort, zu dem gesprungen werden soll, effektiv in einer Tabelle nachgeschlagen wird.
Jede dieser Methoden könnte im Prinzip einen langen Wert anstelle einer ganzen Zahl verwenden. Aber ich denke, es war wahrscheinlich nur eine praktische Entscheidung, die Komplexität des Befehlssatzes und des Compilers mit dem tatsächlichen Bedarf in Einklang zu bringen: Die Fälle, in denen Sie wirklich lange umschalten müssen, sind selten genug, dass es akzeptabel ist, als neu schreiben zu müssen Reihe von IF-Anweisungen oder auf andere Weise umgehen (wenn die fraglichen langen Werte nahe beieinander liegen, können Sie in Ihrem Java-Code das int-Ergebnis des Subtrahierens des niedrigsten Werts umschalten).
Weil sie nicht die notwendigen Anweisungen im Bytecode implementiert haben und Sie wirklich nicht so viele Fälle schreiben möchten, egal wie "produktionsbereit" Ihr Code ist ...
[EDIT: Auszug aus Kommentaren zu dieser Antwort, mit einigen Ergänzungen im Hintergrund]
Um genau zu sein, 2³² sind viele Fälle und jedes Programm mit einer Methode, die lang genug ist, um mehr als das zu halten, wird absolut schrecklich sein! In jeder Sprache. (Die längste Funktion, die ich in einem Code in einer Sprache kenne, ist etwas mehr als 6 KB SLOC - ja, es ist eine große
switch
- und sie ist wirklich nicht zu handhaben.) Wenn Sie wirklich nicht wissen ,long
wo Sie nur eineint
oder weniger haben sollten, dann hast du zwei echte Alternativen.Verwenden Sie eine Variante zum Thema Hash-Funktionen, um die
long
in eine zu komprimierenint
. Die einfachste Möglichkeit, nur wenn Sie den falschen Typ haben, ist das Casting! Nützlicher wäre dies:(int) ((x&0xFFFFFFFF) ^ ((x >>> 32) & 0xFFFFFFFF))
vor dem Einschalten des Ergebnisses. Sie müssen herausfinden, wie Sie die Fälle, gegen die Sie testen, auch transformieren können. Aber wirklich, das ist immer noch schrecklich, da es nicht das eigentliche Problem vieler Fälle anspricht.
Eine viel bessere Lösung, wenn Sie mit einer sehr großen Anzahl von Fällen arbeiten, besteht darin, Ihr Design auf die Verwendung eines
Map<Long,Runnable>
oder eines ähnlichen zu ändern , damit Sie nachschlagen können, wie ein bestimmter Wert versendet wird. Auf diese Weise können Sie die Fälle in mehrere Dateien aufteilen. Dies ist viel einfacher zu verwalten, wenn die Anzahl der Fälle groß wird. Die Organisation der Registrierung des Hosts der beteiligten Implementierungsklassen wird jedoch komplexer (Anmerkungen können hilfreich sein, indem Sie dies zulassen) Registrierungscode automatisch erstellen).FWIW, ich habe dies vor vielen Jahren getan (wir haben im Verlauf des Projekts auf das neu veröffentlichte J2SE 1.2 umgestellt), als ich eine benutzerdefinierte Bytecode-Engine zur Simulation massiv paralleler Hardware erstellt habe (nein, die Wiederverwendung der JVM wäre aufgrund der radikalen Situation nicht geeignet gewesen verschiedene Wert- und Ausführungsmodelle beteiligt) und es hat den Code im Vergleich zu dem großen
switch
, den die C-Version des Codes verwendete, enorm vereinfacht .Um die Take-Home - Nachricht wiederholen, zu wollen ,
switch
auf einelong
ist ein Hinweis darauf , dass Sie entweder die Typen in Ihrem Programm falsch haben oder dass Sie bauen ein System mit so viel Variation beteiligt , dass Sie sollten mithilfe von Klassen werden. In jedem Fall Zeit zum Umdenken.quelle
Map<Long,Runnable>
, um das Problem auf eine ganz andere Weise zu lösen. :-)switch
? Wenn Sie sich für eine endliche Menge so vieler Elemente entscheiden möchten, deutet dies einfach auf einen Fehler in der grundlegenden Gestaltung des Programms hin. Dass die Leute danach fragen, zeigt lediglich an, dass ** sie ihr Design falsch verstanden haben .long
Anzahl von Zeilen haben können, benötige ich speziell nur 4. Dies ist ein Fall, in dem mir einelong
Hand übergeben wird, die angibt, auf welche Zeile reagiert wird, und ich muss je nach Zeile verschiedene Dinge tun. Ich denke, ich könnte auf int umwandeln, aber es hätte mir das Leben leichter gemacht, wenn ich nurswitch
die Variable bearbeitet hätte. So wie es ist, verwende ich stattdessen nur eine Zeichenfolge vonif
undelse if
.long
bedeutet nicht, dass Sie alle Möglichkeiten prüfen werden, genau wie einint
oder ein zu haben,String
bedeutet das auch nicht. Dies bedeutet, dass Ihre Werte, die eine Handvoll sein können, einen großen Bereich haben . Sie könnten ein paar einfache Fälle überprüfen unddefault
für den Rest hineinfallen . Wenn Sie Schichten und Besetzungen durchführen müssen, besteht die Gefahr, dass Sie Daten verlieren. Unterm Strich ist es eine schlechte Java-Designentscheidung, kein Benutzerproblem.Weil der Nachschlagetabellenindex 32 Bit betragen muss.
quelle
switch
muss nicht unbedingt eine Nachschlagetabelle implementiert werden.Eine lange 32-Bit-Architektur wird durch zwei Wörter dargestellt . Stellen Sie sich nun vor, was passieren könnte, wenn die Ausführung der switch-Anweisung aufgrund unzureichender Synchronisation mit ihren hohen 32 Bits von einem Schreibvorgang und den 32 niedrigen von einem anderen einen langen Wert beobachtet! Es könnte versuchen zu gehen ... wer weiß wo! Grundsätzlich irgendwo zufällig. Selbst wenn beide Schreibvorgänge gültige Fälle für die switch-Anweisung darstellen würden, würde ihre lustige Kombination wahrscheinlich weder zum ersten noch zum zweiten führen - oder extrem schlimmer, es könnte zu einem anderen gültigen, aber nicht verwandten Fall führen!
Zumindest mit einem int (oder kleineren Typen), egal wie stark Sie es vermasseln, liest die switch-Anweisung zumindest einen Wert, den jemand tatsächlich geschrieben hat , anstelle eines Werts "aus dem Nichts".
Natürlich kenne ich den tatsächlichen Grund nicht (es ist mehr als 15 Jahre her, ich habe nicht so lange aufgepasst!), Aber wenn Sie erkennen, wie unsicher und unvorhersehbar ein solches Konstrukt sein könnte, werden Sie dem zustimmen Dies ist definitiv ein sehr guter Grund , niemals Longs einzuschalten (und wie es beabsichtigt ist, wird es 32-Bit-Maschinen geben, dieser Grund bleibt gültig).
quelle
if
und das Ergebnis genauso schlecht wäre: falsches Ergebnis ~> falscher Zweig genommen. Erstellen einer langif
-else
-if
Kette anstelle einesswitch
führen würde tatsächlich zu genau dem gleichen Ergebnis.