Question

En Java, lorsque vous faites

int b = 0;
b = b + 1.0;

Vous obtenez une possible perte d'erreur de précision. Mais pourquoi est-ce que si vous faites

int b = 0;
b += 1.0;

Il n'y a pas d'erreur?

Était-ce utile?

La solution

C'est parce que b += 1.0; équivaut à b = (int) ((b) + (1.0));. Les rétrécissement conversion primitive (JLS 5.1.3) est caché dans l'opération d'affectation de composé.

JLS 15,26. 2 opérateurs d'affectation composés (JLS Troisième édition):

  

Une expression d'affectation de composé de la forme E1 op = E2 est équivalent à E1 = (T) ((E1) op (E2)) , où T est le type de E1 , sauf que E1 est évalué qu'une seule fois.

     

Par exemple, le code suivant est correct:

short x = 3;
x += 4.6;
     

et des résultats dans x ayant la valeur 7 parce qu'il est équivalent à:

short x = 3;
x = (short)(x + 4.6);

Cela explique aussi pourquoi les compiles de code suivant:

byte b = 1;
int x = 5;
b += x; // compiles fine!

Mais cela ne fait pas:

byte b = 1;
int x = 5;
b = b + x; // DOESN'T COMPILE!

Vous devez explicitement jeter dans ce cas:

byte b = 1;
int x = 5;
b = (byte) (b + x); // now it compiles fine!

Il convient de noter que la distribution implicite dans les affectations composés fait l'objet de Puzzle 9: Tweedledum dans le merveilleux livre Java Puzzlers . Voici quelques extraits du livre (légèrement modifié par souci de concision):

  

De nombreux programmeurs pensent que x += i; est tout simplement un raccourci pour x = x + i;. Ce n'est pas tout à fait vrai: si le type du résultat est plus large que celle de la variable, l'opérateur d'affectation composé effectue un rétrécissement silencieux conversion primitive

.      

Pour éviter les mauvaises surprises, ne pas utiliser les opérateurs d'affectation composés sur des variables de type byte, short ou char. Lors de l'utilisation des opérateurs d'affectation composés sur des variables de type int, assurez-vous que l'expression sur le côté droit est pas de type long, float ou double. Lors de l'utilisation des opérateurs d'affectation composés sur des variables de type float, assurez-vous que l'expression sur le côté droit est pas de type double. Ces règles sont suffisantes pour empêcher le compilateur de générer des moulages de rétrécissement dangereux.

     

Pour les concepteurs de la langue, il est probablement une erreur pour les opérateurs d'affectation composés pour générer des moulages invisibles; missions composées où la variable a un type plus étroit que le résultat du calcul devrait probablement être illégal.

Le dernier paragraphe est intéressant de noter: C # est beaucoup plus stricte à cet égard (voir C # Language Specification 7.13.2 affectation composé ).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top