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 switchdichiarazioni:
"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 Integere Byte rispettivamente.
Ma questo non suona bene:
Penseresti che poiché 'a' dovrebbe essere assegnabile a un incarico Integerperché char-> intè legale. (Qualsiasi charvalore si adatta a un int.)
Penseresti che poiché 'a' NON dovrebbe essere assegnabile a Byteperché char-> l' byte assegnazione NON è legale. (La maggior parte dei charvalori 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 charvalore a un intquindi box inta 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 Integernon è permesso. Questo spiega l'errore di compilazione nel primo caso.
Si potrebbe pensare che 'a'a Bytenon 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, Shortoppure 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'è 97decimale, che è compreso nell'intervallo per byte( -128a +127).
Questo spiega perché non c'è errore di compilazione nel secondo esempio.
1 - Non possiamo boxare 'a'a Charactere poi allargare Charactera Integerperché Characternon è un sottotipo Java di Integer. È possibile utilizzare una conversione di riferimento allargata solo se il tipo di origine è un sottotipo del tipo di destinazione.