Les raisons sont assez compliquées, mais elles se trouvent toutes dans les détails (en petits caractères si vous le souhaitez) de la spécification du langage Java.
Tout d'abord, le JLS 14.11 dit ce qui suit au sujet des switch
déclarations:
"Chaque constante de cas associée à l'instruction switch doit être compatible avec le type d'expression de l'instruction switch ( §5.2 )."
Cela signifie que 'a'
doit être attribuable à Integer
et Byte
respectivement.
Mais cela ne semble pas juste:
On pourrait penser que puisque 'a'
devrait être attribuable à une affectation Integer
car char
-> int
est légale. (Toute char
valeur rentrera dans un int
.)
Vous penseriez que puisque 'a'
ne devrait PAS être attribuable à une affectation Byte
parce que char
-> byte
n'est PAS légal. (La plupart des char
valeurs ne rentrent pas dans un octet.)
En fait, ni l'un ni l'autre n'est correct. Pour comprendre pourquoi, nous devons lire ce que JLS 5.2 fait réellement sur ce qui est autorisé dans les contextes d'affectation.
"Les contextes d'affectation permettent d'utiliser l' un des éléments suivants :
- une conversion d'identité (§5.1.1)
- une conversion primitive élargie (§5.1.2)
- une conversion de référence élargie (§5.1.5)
- une conversion de référence élargie suivie d'une conversion de déballage
- une conversion de référence élargie suivie d'une conversion de déballage, puis suivie d'une conversion primitive d'élargissement
- une conversion de boxe (§5.1.7)
- une conversion de boxe suivie d'une conversion de référence élargie
- une conversion de déballage (§5.1.8)
- une conversion unboxing suivie d'une conversion primitive élargie. "
Pour passer de 'a'
à Integer
, il faudrait 1 élargir la char
valeur à an int
puis encadrer la int
à an Integer
. Mais si vous regardez les combinaisons de conversions autorisées, vous ne pouvez pas faire une conversion primitive élargie suivie d'une conversion de boxe.
Par conséquent , 'a'
à Integer
n'est pas autorisé. Cela explique l'erreur de compilation dans le premier cas.
On pourrait penser que 'a'
to Byte
est interdit car cela impliquerait une conversion de rétrécissement primitive ... qui n'est pas du tout dans la liste. En fait, les littéraux sont un cas particulier. JLS 5.2 poursuit en disant ce qui suit.
"De plus, si l'expression est une expression constante ( §15.28 ) de type octet, court, char ou int:
Une conversion primitive rétrécissante peut être utilisée si la variable est de type byte, short ou char, et que la valeur de l'expression constante est représentable dans le type de la variable.
Un rétrécissement de conversion primitive suivie d'une conversion de boxe peuvent être utilisés si la variable est de type Byte
, Short
, ou Character
, et la valeur de l'expression constante est représentable dans l'octet de type, court, ou char respectivement « .
La seconde s'applique 'a'
à Byte
, car:
- un littéral de caractère est une expression constante, et
- la valeur de
'a'
est 97
décimale, qui se situe dans la plage de byte
( -128
à +127
).
Cela explique pourquoi il n'y a pas d'erreur de compilation dans le deuxième exemple.
1 - Nous ne pouvons pas boxer 'a'
vers a Character
puis élargir Character
vers Integer
car il Character
ne s'agit pas d'un sous-type Java de Integer
. Vous ne pouvez utiliser une conversion de référence élargie que si le type source est un sous-type du type cible.