Ich frage mich nur, warum die Java 7- switch
Anweisung keinen null
Fall unterstützt und stattdessen wirft NullPointerException
. Siehe die kommentierte Zeile unten (Beispiel aus dem Artikel über Java-Tutorialsswitch
):
{
String month = null;
switch (month) {
case "january":
monthNumber = 1;
break;
case "february":
monthNumber = 2;
break;
case "march":
monthNumber = 3;
break;
//case null:
default:
monthNumber = 0;
break;
}
return monthNumber;
}
Dies hätte eine if
Bedingung für eine Nullprüfung vor jeder switch
Verwendung vermieden .
java
switch-statement
language-design
Prashant Bhate
quelle
quelle
null
führt zu einer Ausnahme. Führen Sie eineif
Prüfung durchnull
und gehen Sie dann in dieswitch
Anweisung.NullPointerException
Ansicht der Entwickler der Java-Programmiersprache ist [das Auslösen eines if, wenn der Ausdruck zurnull
Laufzeit ausgewertet wird] ein besseres Ergebnis, als die gesamte switch-Anweisung stillschweigend zu überspringen oder die Anweisungen (falls vorhanden) nach dem auszuführen Standardbezeichnung (falls vorhanden).Antworten:
Wie damryfbfnetsi weist darauf hin , in den Kommentaren, JLS §14.11 hat die folgende Anmerkung:
(Hervorhebung von mir)
Während der letzte Satz die Möglichkeit der Verwendung überspringt
case null:
, erscheint er vernünftig und bietet einen Einblick in die Absichten der Sprachdesigner.Wenn wir uns eher die Implementierungsdetails ansehen, enthält dieser Blog-Beitrag von Christian Hujer einige aufschlussreiche Spekulationen darüber, warum
null
Switches nicht zulässig sind (obwohl er sichenum
eher auf den Switch als auf denString
Switch konzentriert):Während
String
Switches unterschiedlich implementiert sind , stand derenum
Switch an erster Stelle und legte den Präzedenzfall für das Verhalten eines Referenztyps fest, wenn sich die Referenz befindetnull
.quelle
case null:
wenn sie exklusiv für implementiert worden wäreString
. GegenwärtigString
erfordert jede Überprüfung ohnehin eine Nullprüfung, wenn wir dies korrigieren möchten, obwohl dies meistens implizit geschieht, indem die Zeichenfolgenkonstante wie in zuerst gesetzt wird"123test".equals(value)
. Jetzt sind wir gezwungen, unsere switch-Anweisung wie inif (value != null) switch (value) {...
Im Allgemeinen
null
ist es böse zu handhaben; Vielleicht kann eine bessere Sprache ohne lebennull
.Ihr Problem könnte durch gelöst werden
quelle
month
es sich um eine leere Zeichenfolge handelt: Dadurch wird sie genauso behandelt wie eine Nullzeichenfolge.Es ist nicht schön, aber
String.valueOf()
Sie können einen Null-String in einem Switch verwenden. Wenn es findetnull
, konvertiert es es in"null"
, andernfalls gibt es nur den gleichen String zurück, den Sie übergeben haben. Wenn Sie nicht"null"
explizit behandeln, wird es zu gehendefault
. Die einzige Einschränkung ist, dass es keine Möglichkeit gibt, zwischen dem String"null"
und einer tatsächlichennull
Variablen zu unterscheiden.quelle
Dies ist ein Versuch zu beantworten, warum es wirft
NullPointerException
Die Ausgabe des folgenden javap-Befehls zeigt, dass
case
er basierend auf dem Hashcode derswitch
Argumentzeichenfolge ausgewählt wurde und daher NPE auslöst, wenn er.hashCode()
für eine Nullzeichenfolge aufgerufen wird.Dies bedeutet, basierend auf den Antworten auf Kann Javas HashCode denselben Wert für verschiedene Zeichenfolgen erzeugen? Obwohl selten, besteht immer noch die Möglichkeit, dass zwei Fälle übereinstimmen (zwei Zeichenfolgen mit demselben Hashcode). Siehe dieses Beispiel unten
Javap für welche
Wie Sie sehen können, wird nur ein Fall für
"Ea"
und"FB"
mit zweiif
Bedingungen generiert , um eine Übereinstimmung mit jeder Fallzeichenfolge zu überprüfen. Sehr interessante und komplizierte Art der Implementierung dieser Funktionalität!quelle
hashCode
verschiedenen Programmläufen dieselben Werte zurückgegeben werden, sondern dass String-Hashes von in ausführbare Dateien gebacken werden Im Compiler ist die String-Hash-Methode Teil der Sprachspezifikation.Lange Rede, kurzer Sinn ... (und hoffentlich interessant genug !!!)
Enum wurde erstmals in Java1.5 ( September 2004 ) eingeführt, und der Fehler , der das Einschalten des Strings zuließ, wurde vor langer Zeit ( Oktober 1995 ) abgelegt . Wenn Sie sich den Kommentar ansehen, der zu diesem Fehler im Juni 2004 veröffentlicht wurde , heißt es, dass
Don't hold your breath. Nothing resembling this is in our plans.
sie diesen Fehler zurückgestellt ( ignoriert ) und schließlich Java 1.5 im selben Jahr gestartet haben, in dem sie 'enum' mit Ordnungszahl ab 0 eingeführt und entschieden haben ( verpasst ), um null für enum nicht zu unterstützen. Später in Java1.7 ( Jul'2011 ) folgten sie ( gezwungen) die gleiche Philosophie wie bei String (dh beim Generieren des Bytecodes wurde vor dem Aufruf der Methode hashcode () keine Nullprüfung durchgeführt).Ich denke, es läuft darauf hinaus, dass die Aufzählung zuerst einging und mit dem ordinalen Start bei 0 implementiert wurde, aufgrund dessen sie den Nullwert im Schalterblock nicht unterstützen konnten, und später mit String beschlossen sie, dieselbe Philosophie zu erzwingen, dh den Nullwert nicht im Schalterblock erlaubt.
TL; DR Mit String hätten sie sich um NPE kümmern können (verursacht durch den Versuch, Hashcode für null zu generieren), während sie die Konvertierung von Java-Code in Byte-Code implementierten, sich aber schließlich dagegen entschieden.
Ref: TheBUG , JavaVersionHistory , JavaCodeToByteCode , SO
quelle
Laut Java Docs:
Da
null
es keinen Typ hat und keine Instanz von irgendetwas ist, funktioniert es nicht mit einer switch-Anweisung.quelle
null
ist ein gültiger Wert für eineString
,Character
,Byte
,Short
, oderInteger
Referenz.Die Antwort lautet einfach: Wenn Sie einen Switch mit einem Referenztyp (z. B. einem primitiven Typ mit Box) verwenden, tritt der Laufzeitfehler auf, wenn der Ausdruck null ist, da durch das Entpacken die NPE ausgelöst wird.
Fall null (was illegal ist) könnte also sowieso nie ausgeführt werden;)
quelle
if (x == null) { // the case: null part }
Ich stimme aufschlussreichen Kommentaren (unter der Haube ...) in https://stackoverflow.com/a/18263594/1053496 in der Antwort von @Paul Bellora zu.
Ich habe aus meiner Erfahrung einen weiteren Grund gefunden.
Wenn 'case' null sein kann, was bedeutet, dass switch (variable) null ist, können wir argumentieren, dass es in Ordnung ist, solange der Entwickler einen passenden 'null'-Fall bereitstellt. Was passiert jedoch, wenn der Entwickler keinen passenden Nullfall bereitstellt? Dann müssen wir es einem 'Standard'-Fall zuordnen, der möglicherweise nicht das ist, was der Entwickler im Standardfall beabsichtigt hat. Daher kann das Anpassen von 'null' an einen Standardwert 'überraschendes Verhalten' verursachen. Wenn Sie also 'NPE' auslösen, kann der Entwickler alle Fälle explizit behandeln. Ich fand das Werfen von NPE in diesem Fall sehr nachdenklich.
quelle
Verwenden Sie die Apache StringUtils-Klasse
quelle