Kompiliert nicht:
void test(Integer x) {
switch (x) {
case 'a':
}
}
Kompiliert OK:
void test(Byte x) {
switch(x) {
case 'a':
}
}
java
java-8
switch-statement
ali gh
quelle
quelle
'a'
Fall wird in dem Fall ausgeführt werden , dassx
das Byte97
. (Versuchen Sie es, wenn Sie mir nicht glauben.) Die wirkliche Erklärung finden Sie in meiner Antwort.Antworten:
Die Gründe sind ziemlich kompliziert, aber sie liegen alle in den Details ( Kleingedrucktes, wenn Sie möchten) der Java-Sprachspezifikation.
Zunächst sagt der JLS 14.11 Folgendes über
switch
Aussagen:Dies bedeutet , dass
'a'
zuordenbar sein mussInteger
undByte
jeweils.Das klingt aber nicht richtig:
Sie würden denken, dass da
'a'
einem zuweisbar sein sollte,Integer
weilchar
->int
Zuordnung legal ist. (Jederchar
Wert passt in eineint
.)Sie würden denken, dass da
'a'
NICHT einer zuweisbar sein sollte,Byte
weilchar
->byte
Zuordnung NICHT legal ist. (Die meistenchar
Werte passen nicht in ein Byte.)In der Tat ist keines davon richtig. Um zu verstehen, warum, müssen wir lesen, was JLS 5.2 tatsächlich über das erlaubt, was in Zuweisungskontexten zulässig ist.
Um von zu
'a'
zu gelangenInteger
, müssten wir den Wert auf 1 erweiternchar
undint
dannint
auf einen Wert setzenInteger
. Wenn Sie sich jedoch die zulässigen Kombinationen von Conversions ansehen, können Sie keine erweiterte primitive Conversion gefolgt von einer Box-Conversion durchführen.Daher ist
'a'
toInteger
nicht erlaubt. Dies erklärt den Kompilierungsfehler im ersten Fall.Sie würden denken, dass
'a'
toByte
nicht erlaubt ist, da dies eine primitive Verengungskonvertierung beinhalten würde ... die überhaupt nicht in der Liste enthalten ist. In der Tat sind Literale ein Sonderfall. JLS 5.2 führt Folgendes aus.Die zweite davon gilt
'a'
fürByte
, weil:'a'
ist97
dezimal und liegt innerhalb des Bereichs fürbyte
(-128
bis+127
).Dies erklärt, warum im zweiten Beispiel kein Kompilierungsfehler vorliegt.
1 - Wir können nicht Box
'a'
auf einCharacter
und dann erweiternCharacter
auf ,Integer
weilCharacter
kein Java - SubtypInteger
. Sie können eine erweiterte Referenzkonvertierung nur verwenden, wenn der Quelltyp ein Subtyp des Zieltyps ist.quelle
int
als Schaltertyp verwenden? (dachar -> int
ist primitive Erweiterung, die erlaubt ist)