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 switchdeclarações:
"Toda constante de caso associada à instrução switch deve ser atribuída compatível com o tipo de expressão da instrução switch ( §5.2 )."
Isso significa que 'a'precisa ser atribuível Integere Byte respectivamente.
Mas isso não parece certo:
Você pensaria que desde que 'a' deve ser atribuível a uma Integerporque char-> int atribuição é legal. (Qualquer charvalor caberá em um int.)
Você pensaria que uma vez 'a' que NÃO deve ser atribuível a uma Byteporque char-> a byte atribuição NÃO é legal. (A maioria dos charvalores 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.
"Os contextos de atribuição permitem o uso de um dos seguintes :
- uma conversão de identidade (§5.1.1)
- uma conversão primitiva alargada (§5.1.2)
- uma conversão de referência ampliada (§5.1.5)
- uma conversão de referência ampliada seguida por uma conversão de unboxing
- uma conversão de referência de ampliação seguida por uma conversão de unboxing e, em seguida, uma conversão primitiva de ampliação
- uma conversão de boxe (§5.1.7)
- uma conversão de boxe seguida por uma conversão de referência ampliada
- uma conversão de unboxing (§5.1.8)
- uma conversão de unboxing seguida por uma conversão primitiva de ampliação ".
Para passar de 'a'para Integer, precisaríamos 1 ampliar o charvalor para uma intcaixa e depois a intpara um Integer. 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'a Integernão é permitido. Isso explica o erro de compilação no primeiro caso.
Você poderia pensar que 'a'a Bytenã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.
"Além disso, se a expressão for uma expressão constante ( §15.28 ) do tipo byte, short, char ou int:
Uma conversão primitiva de restrição pode ser usada se a variável for do tipo byte, curta ou char, e o valor da expressão constante for representável no tipo da variável.
Uma conversão primitivo estreitando seguido por uma conversão boxe pode ser usado se a variável é do tipo Byte, Shortou Character, e o valor da expressão constante é representável no tipo byte, curto, ou carvão animal, respectivamente ".
O segundo deles se aplica 'a'a Byte, porque:
- um literal de caractere é uma expressão constante e
- o valor de
'a'é 97decimal, que está dentro do intervalo de byte( -128para +127).
Isso explica por que não há erro de compilação no segundo exemplo.
1 - Não pode caixa 'a'a um Charactere depois ampliar Characterpara Integerporque Characternão é um subtipo Java Integer. Você só pode usar uma conversão de referência ampliada se o tipo de origem for um subtipo do tipo de destino.