web-dev-qa-db-fra.com

Pourquoi "int i = 2147483647 + 1;" OK, mais "octet b = 127 + 1;" n'est pas compilable?

Pourquoi est-ce int i = 2147483647 + 1; OK mais byte b = 127 + 1; n'est pas compilable?

126
goku

Les constantes sont évaluées comme des entiers, donc 2147483647 + 1 déborde et vous donne un nouvel entier, qui est assignable à int, tandis que 127 + 1 également évalué comme int est égal à 128, et il n'est pas attribuable à byte.

172
MByD

Le littéral 127 dénote une valeur de type int. Il en va de même pour le littéral 1. La somme de ces deux est l'entier 128. Le problème, dans le deuxième cas, est que vous l'assignez à une variable de type octet. Cela n'a rien à voir avec la valeur réelle des expressions. Cela a à voir avec Java ne supporte pas les coercitions (*). Vous devez ajouter un transtypage

byte b = (byte)(127 + 1);

puis il compile.

(*) du moins pas du type String-to-integer, float-to-Time, ... Java supporte les coercitions si elles sont, dans un sens, sans perte (Java appelle cela "élargissement").

Et non, le mot "coercition" n'avait pas besoin d'être corrigé. Il a été choisi très délibérément et correctement. De la source la plus proche à la main (Wikipedia): "Dans la plupart des langues, la coercition Word est utilisée pour désigner un  implicite conversion, que ce soit pendant la compilation ou pendant l'exécution. "et" En informatique, la conversion de type, la transtypage et la coercition sont différents = moyens de transformer, implicitement ou explicitement, une entité d'un type de données par un autre. ".

35
Erwin Smout

Comme preuve pour @MByD:

Le code suivant se compile:

byte c = (byte)(127 + 1);

Parce que bien que l'expression (127 + 1) est entier et au-delà de la portée hors byte tapez le résultat est casté en byte. Cette expression produit -128.

6
AlexR

Conversion d'affectation JLS3 # 5.2

(variable = expression)

De plus, si l'expression est une expression constante (§15.28) de type byte, short, char ou int:

Une conversion primitive de rétrécissement peut être utilisée si le type de la variable est octet, court ou caractère et que la valeur de l'expression constante est représentable dans le type de la variable.


Sans cette clause, nous ne pourrions pas écrire

byte x = 0;
char c = 0;

Mais devrions-nous être en mesure de le faire? Je ne pense pas. Il y a pas mal de magie en cours de conversion entre les primitives, il faut être très prudent. Je ferais tout mon possible pour écrire

byte x = (byte)0;
3
irreputable