En Java, les opérations suivantes sont autorisées:
char c = 'A' + 1;
Ici, c tiendra la valeur 'B'. Ci-dessus, d'abord l'expression est évaluée. Ainsi, "A" est converti en 65, l'expression entière est évaluée à 66, puis 66 est convertie en "B" car nous stockons la valeur dans un caractère.
Ce qui suit donne cependant une erreur lors de la compilation:
char c = 'A';
c = c + 1;
Quelle est l'explication de la façon dont Java considère les expressions différemment? Au fait, les choses suivantes fonctionnent aussi:
char c = 'A';
c++;
Le premier exemple (qui compile) est spécial car l'addition a lieu dans l'initialiseur de la variable et les deux opérandes sont des littéraux.
Quelques définitions pour commencer:
La conversion d'une int
en char
s'appelle un conversion primitive restrictive , parce que char
est un type plus petit que int
.
'A' + 1
est un expression constante . Une expression constante est (fondamentalement) une expression dont le résultat est toujours le même et peut être déterminé au moment de la compilation. 'A' + 1
est en particulier une expression constante car les opérandes de +
sont tous les deux des littéraux.
De plus, si l'expression [à droite] est une expression constante de type
byte
,short
,char
ouint
:
- Une conversion primitive restrictive peut être utilisée si la variable est de type
byte
,short
ouchar
et que la valeur de l'expression constante est représentable dans le type de la variable.
c + 1
est pas une expression constante, parce que c
est une variable non -final
, de sorte qu'une erreur de compilation survient pour l'affectation. En regardant le code, nous peut déterminer que le résultat est toujours le même, mais le compilateur n'est pas autorisé à le faire dans ce cas.
Une chose intéressante que nous pouvons faire est la suivante:
final char a = 'a';
char b = a + 1;
Dans ce cas, a + 1
est une expression constante, car a
est une variable final
qui est initialisée avec une expression constante.
La mise en garde "si […] la valeur […] est représentable dans le type de la variable" signifie que les éléments suivants ne seraient pas compilés:
char c = 'A' + 99999;
La valeur de 'A' + 99999
(qui est 100064
ou 0x186E0
) est trop grande pour tenir dans une char
, car char
est un entier non signé de 16 bits .
Comme pour l'opérateur postfix ++
:
Le type de l'expression postfix increment est le type de la variable.
...
Avant l'ajout, une promotion numérique binaire * est effectuée sur la valeur
1
et la valeur de la variable. Si nécessaire, la somme est rétrécie par une conversion primitive restrictive et/ou soumise à une conversion de boxe au type de la variable avant son stockage.
(* Promotion numérique binaire prend les opérandes byte
, short
et char
d'opérateurs tels que +
et les convertit en int
ou en un autre type plus gros. Java ne fait pas d'arithmétique sur des types intégraux plus petits que int
. )
En d'autres termes, l'instruction c++;
est généralement équivalente à:
c = (char)(c + 1);
(La différence est que le résultat de l'expression c++
, si nous l'attribuons à quelque chose, correspond à la valeur de c
_ avant l'incrément.)
Les autres incréments et décréments ont des spécifications très similaires.
Les opérateurs d'assignation composés tels que +=
effectuent également automatiquement la conversion de rétrécissement , ainsi des expressions telles que c += 1
(ou même c += 3.14
) sont également autorisées.
la conversion char en int est appelée élargissement des conversions. Lors de l'élargissement des conversions, les valeurs ne perdent pas d'informations sur la magnitude globale d'une valeur numérique, la conversion d'un caractère à l'autre étant appelée conversion de rétrécissement. Avec une conversion plus étroite, vous risquez de perdre des informations sur la magnitude globale d'une valeur numérique, ainsi que de perdre en précision.
Pour plus d'informations sur les conversions primitives, reportez-vous à this document.
C'est parce que le compilateur peut vérifier qu'il ('A' + 1)
est dans les limites d'un caractère alors qu'il ne peut pas (en général) vérifier que c + <an integer>
est dans les limites.
C'est parce que les littéraux de nombre entier ou inférieur à int, tels que byte, short et char, sont int . Comprenez ce qui suit de cette façon.
code:
byte a = 10;//compile fine
byte b= 11;//compile fine
byte c = a+b;//compiler error[says that result of **a+b** is **int**]
il en est de même pour toutes les opérations mathématiques telles que «Diviser», «Multiplier» et toute autre opération arithmétique. alors lancez le résultat pour obtenir le littéral dans le type de données souhaité
byte c = (byte)(a+b);
alors quand vous effectuez
c= c+1;//compiler error
C'est le résultat de c + 1 qui est int pas un caractère. donc le compilateur donne une erreur de compilation pour le même . vous devez donc fournir une distribution primitive pour changer le littéral en type de données char.