Los motivos son bastante complicados, pero todos están en los detalles ( letra pequeña si lo desea) de la Especificación del lenguaje Java.
Primero, el JLS 14.11 dice lo siguiente sobre las switch
declaraciones:
"Cada constante de caso asociada con la declaración del interruptor debe ser compatible con el tipo de expresión de la declaración del interruptor ( §5.2 )".
Esto significa que 'a'
debe ser asignable a Integer
y Byte
respectivamente.
Pero eso no suena bien:
Se podría pensar que ya 'a'
debería ser asignable a un Integer
porque char
-> la int
asignación es legal. (Cualquier char
valor encajará en un int
.)
Pensaría que ya 'a'
NO debería poder asignarse a un Byte
porque char
-> la byte
asignación NO es legal. (La mayoría de los char
valores no caben en un byte).
De hecho, ninguno de estos es correcto. Para entender por qué, necesitamos leer lo que JLS 5.2 realmente trata sobre lo que está permitido en contextos de asignación.
"Los contextos de asignación permiten el uso de uno de los siguientes :
- una conversión de identidad (§5.1.1)
- una conversión primitiva cada vez mayor (§5.1.2)
- Una conversión de referencia cada vez mayor (§5.1.5)
- una conversión de referencia cada vez mayor seguida de una conversión de unboxing
- una conversión de referencia de ampliación seguida de una conversión de unboxing, seguida de una conversión primitiva de ampliación
- una conversión de boxeo (§5.1.7)
- una conversión de boxeo seguida de una conversión de referencia cada vez mayor
- una conversión de unboxing (§5.1.8)
- una conversión de unboxing seguida de una conversión primitiva cada vez mayor ".
Para ir de 'a'
a Integer
, necesitaríamos 1 ampliar el char
valor a un int
cuadro luego int
a Integer
. Pero si observa las combinaciones de conversiones permitidas, no puede hacer una conversión primitiva de ampliación seguida de una conversión de boxeo.
Por lo tanto, 'a'
a Integer
que no está permitido. Esto explica el error de compilación en el primer caso.
Se podría pensar que 'a'
al Byte
no está permitida ya que se incurriría una conversión de restricción primitiva ... que no está en la lista en absoluto. De hecho, los literales son un caso especial. JLS 5.2 continúa diciendo lo siguiente.
"Además, si la expresión es una expresión constante ( §15.28 ) de tipo byte, short, char o int:
Se puede usar una conversión primitiva estrecha si la variable es de tipo byte, short o char, y el valor de la expresión constante es representable en el tipo de la variable.
Se puede usar una conversión primitiva de estrechamiento seguida de una conversión de boxeo si la variable es de tipo Byte
,, Short
o Character
, y el valor de la expresión constante es representable en el byte de tipo, short o char respectivamente ".
El segundo de estos se aplica 'a'
a Byte
, porque:
- un carácter literal es una expresión constante y
- el valor de
'a'
es 97
decimal, que está dentro del rango de byte
( -128
a +127
).
Esto explica por qué no hay error de compilación en el segundo ejemplo.
1 - No podemos encajonar 'a'
a Character
ay luego ampliar Character
a Integer
porque Character
no es un subtipo de Java Integer
. Solo puede usar una conversión de referencia de ampliación si el tipo de origen es un subtipo del tipo de destino.