45 votes

Primitive de fonte et les affectations en Java

Je comprends pourquoi le suivant est incorrect:

byte a = 3; 
byte b = 8; 
byte c = a + b;  // compile error

Il ne compile pas. Expressions toujours un int. Nous avons fait le cast explicite:

byte c = (byte) (a + b);   // valid code

Mais je ne comprends pas pourquoi la suivante est correcte:

byte d = 3 + 8;   // it's valid! why?

Parce que littéral entier (comme les 3 ou 8) est toujours implicitement un int. Et int-or-smaller expressions toujours un int trop. Quelqu'un peut-il expliquer ce qui se passe ici?

La seule chose que je peux deviner, c'est que le compilateur correspond cette expression à la suivante:

byte d = 11;

et ne considère pas cette expression.

46voto

Jason Points 125291

Cela a moins† à faire avec si ou pas, 3 + 8 est évaluée à l' 11 au moment de la compilation, et plus à voir avec le fait que le compilateur est explicitement autorisé implicitement une étroite ints pour bytes dans certains cas. En particulier, la spécification du langage permet explicitement implicite rétrécissement des conversions à l' byte d'expressions constantes de type int qui peut s'adapter à un byte au moment de la compilation.

La section pertinente de la JLS ici est l'article §5.2:

En outre, si l'expression est une expression constante (§15.28) de type byte, short, charou int:

  • Un rétrécissement primitive de la conversion peut être utilisé si le type de la variable byte, shortou char, et la valeur de la constante l'expression est représentable dans le type de la variable.

Le moment de la compilation rétrécissement des constantes signifie que le code tel que: byte theAnswer = 42; est autorisée. Sans la réduction, le fait que l'entier littéral 42 type intserait dire qu'une troupe de byte serait nécessaire:

†: Évidemment, comme pour la spécification, la constante de l'expression doit être évaluée afin de voir si elle s'inscrit dans la plus étroite de type ou pas. Mais le point saillant est que sans cette section de la spécification, le compilateur ne seraient pas autorisés à faire de l'implicite rétrécissement de conversion.

Soyons clairs ici:

byte a = 3; 
byte b = 8; 

La raison que ces sont autorisés en raison de la section ci-dessus de la spécification. C'est le compilateur est autorisé à faire l'implicite rétrécissement de conversion de l'littérale 3 d'un byte. Ce n'est pas parce que le compilateur évalue l'expression constante 3 de sa valeur en 3 au moment de la compilation.

41voto

fge Points 40850

La seule chose que je peux deviner, c'est que le compilateur correspond cette expression à la suivante:

Oui, c'est fait. Aussi longtemps que le côté droit de l'expression est faite de constantes (qui correspondent aux requis de type primitif -- voir @Jason réponse à ce que le JLS dit à propos de ce exactement), vous pouvez le faire. Ce ne sera pas compiler, car 128 est hors de la plage:

byte a = 128;

Notez que si vous transformez votre premier extrait de code comme ceci:

final byte a = 3; 
final byte b = 8; 
byte c = a + b;

il compile! Que votre deux octets sont final et leurs expressions sont des constantes, cette fois, le compilateur peut déterminer que le résultat tient dans un octet quand il est d'abord initialisé.

Ceci, cependant, ne sera pas de la compilation:

final byte a = 127; // Byte.MAX_VALUE
final byte b = 1;
byte c = a + b // Nope...

Le compilateur d'erreur avec un "possible perte de précision".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X