Le ragioni sono piuttosto complicate, ma sono tutte nei dettagli ( stampa fine se preferisci) della specifica del linguaggio Java.
Innanzitutto, JLS 14.11 afferma quanto segue sulle switch
dichiarazioni:
"Ogni costante di caso associata all'istruzione switch deve essere compatibile con il tipo di espressione dell'istruzione switch ( §5.2 )."
Ciò significa che 'a'
deve essere assegnabile a Integer
e Byte
rispettivamente.
Ma questo non suona bene:
Penseresti che poiché 'a'
dovrebbe essere assegnabile a un incarico Integer
perché char
-> int
è legale. (Qualsiasi char
valore si adatta a un int
.)
Penseresti che poiché 'a'
NON dovrebbe essere assegnabile a Byte
perché char
-> l' byte
assegnazione NON è legale. (La maggior parte dei char
valori non si adatta a un byte.)
In effetti, nessuno di questi è corretto. Per capire perché, dobbiamo leggere cosa JLS 5.2 in realtà su ciò che è consentito nei contesti di assegnazione.
"I contesti di assegnazione consentono l'uso di uno dei seguenti :
- una conversione di identità (§5.1.1)
- una conversione primitiva allargante (§5.1.2)
- una conversione di riferimento allargata (§5.1.5)
- una conversione di riferimento allargata seguita da una conversione unboxing
- una conversione di riferimento allargata seguita da una conversione unboxing, quindi seguita da una conversione primitiva allargante
- una conversione di boxe (§5.1.7)
- una conversione di inscatolamento seguita da una conversione di riferimento allargata
- una conversione unboxing (§5.1.8)
- una conversione unboxing seguita da una conversione primitiva allargata. "
Per passare da 'a'
a Integer
, avremmo bisogno di 1 allargare il char
valore a un int
quindi box int
a a un Integer
. Ma se osservi le combinazioni di conversioni consentite, non puoi fare una conversione primitiva allargata seguita da una conversione di boxe.
Quindi 'a'
per Integer
non è permesso. Questo spiega l'errore di compilazione nel primo caso.
Si potrebbe pensare che 'a'
a Byte
non sia consentito perché ciò implicherebbe una conversione restrittiva primitiva ... che non è affatto nell'elenco. In effetti, i letterali sono un caso speciale. JLS 5.2 continua dicendo quanto segue.
"Inoltre, se l'espressione è un'espressione costante ( §15.28 ) di tipo byte, short, char o int:
Una conversione primitiva restrittiva può essere utilizzata se la variabile è di tipo byte, short o char e il valore dell'espressione costante è rappresentabile nel tipo di variabile.
Una conversione primitiva restrittiva seguita da una conversione di inscatolamento può essere utilizzata se la variabile è di tipo Byte
, Short
oppure Character
, e il valore dell'espressione costante è rappresentabile nel byte di tipo, breve o char rispettivamente ".
Il secondo si applica 'a'
a Byte
, perché:
- un personaggio letterale è un'espressione costante, e
- il valore di
'a'
è 97
decimale, che è compreso nell'intervallo per byte
( -128
a +127
).
Questo spiega perché non c'è errore di compilazione nel secondo esempio.
1 - Non possiamo boxare 'a'
a Character
e poi allargare Character
a Integer
perché Character
non è un sottotipo Java di Integer
. È possibile utilizzare una conversione di riferimento allargata solo se il tipo di origine è un sottotipo del tipo di destinazione.