Não compila:
void test(Integer x) {
switch (x) {
case 'a':
}
}
Compila OK:
void test(Byte x) {
switch(x) {
case 'a':
}
}
java
java-8
switch-statement
ali gh
fonte
fonte
'a'
caso será executado no caso quex
é o byte97
. (Tente se você não acredita em mim.) Para obter uma explicação real, veja minha resposta.Respostas:
Os motivos são bastante complicados, mas estão todos nos detalhes ( letras pequenas, se você preferir ) da Especificação de Linguagem Java.
Primeiro, o JLS 14.11 diz o seguinte sobre
switch
declarações:Isso significa que
'a'
precisa ser atribuívelInteger
eByte
respectivamente.Mas isso não parece certo:
Você pensaria que desde que
'a'
deve ser atribuível a umaInteger
porquechar
->int
atribuição é legal. (Qualquerchar
valor caberá em umint
.)Você pensaria que uma vez
'a'
que NÃO deve ser atribuível a umaByte
porquechar
-> abyte
atribuição NÃO é legal. (A maioria doschar
valores não cabe em um byte.)De fato, nenhuma delas está correta. Para entender o porquê, precisamos ler o JLS 5.2 sobre o que é permitido nos contextos de atribuição.
Para passar de
'a'
paraInteger
, precisaríamos 1 ampliar ochar
valor para umaint
caixa e depois aint
para umInteger
. Mas se você observar as combinações de conversões permitidas, não poderá fazer uma conversão primitiva de ampliação seguida por uma conversão de boxe.Portanto
'a'
aInteger
não é permitido. Isso explica o erro de compilação no primeiro caso.Você poderia pensar que
'a'
aByte
não é permitido porque isso envolveria uma conversão de restrição primitiva ... que não está na lista de todo. De fato, literais são um caso especial. O JLS 5.2 continua dizendo o seguinte.O segundo deles se aplica
'a'
aByte
, porque:'a'
é97
decimal, que está dentro do intervalo debyte
(-128
para+127
).Isso explica por que não há erro de compilação no segundo exemplo.
1 - Não pode caixa
'a'
a umCharacter
e depois ampliarCharacter
paraInteger
porqueCharacter
não é um subtipo JavaInteger
. Você só pode usar uma conversão de referência ampliada se o tipo de origem for um subtipo do tipo de destino.fonte
int
como o tipo de switch? (uma vez quechar -> int
é alargamento primitivo que é permitido)