Question Pourquoi les opérateurs d'assignation composés Java + =, - =, * =, / = ne nécessitent-ils pas le cast?


Jusqu'à aujourd'hui, je pensais que par exemple:

i += j;

est juste un raccourci pour:

i = i + j;

Mais si nous essayons cela:

int i = 5;
long j = 8;

alors i = i + j; ne compilera pas mais i += j; compilera bien.

Cela signifie-t-il qu'en fait i += j; est un raccourci pour quelque chose comme ça i = (type of i) (i + j)?


3283
2018-01-03 10:10


origine


Réponses:


Comme toujours avec ces questions, le JLS détient la réponse. Dans ce cas §15.26.2 Opérateurs d'assignation composée. Un extrait:

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

Un exemple cité de §15.26.2

[...] le code suivant est correct:

short x = 3;
x += 4.6;

et résulte en x ayant la valeur 7 car il est équivalent à:

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

En d'autres termes, votre hypothèse est correcte.


2210
2018-01-03 10:15



Un bon exemple de ce casting est l'utilisation de * = ou / =

byte b = 10;
b *= 5.7;
System.out.println(b); // prints 57

ou

byte b = 100;
b /= 2.5;
System.out.println(b); // prints 40

ou

char ch = '0';
ch *= 1.1;
System.out.println(ch); // prints '4'

ou

char ch = 'A';
ch *= 1.5;
System.out.println(ch); // prints 'a'

442
2018-01-03 10:20



Très bonne question le Java Language spécification confirme votre suggestion.

Par exemple, le code suivant est correct:

short x = 3;
x += 4.6;

et résulte en x ayant la valeur 7 car il est équivalent à:

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

223
2018-01-03 10:17



Oui,

fondamentalement quand nous écrivons

i += l; 

le compilateur convertit cela en

i = (int)(i + l);

Je viens de vérifier le .class code de fichier.

Vraiment une bonne chose à savoir


163
2018-01-03 10:19



vous devez lancer de long à int  explicitly en cas de i = i + l  alors il va compiler et donner une sortie correcte. comme

i = i + (int)l;

ou

i = (int)((long)i + l); // this is what happens in case of += , dont need (long) casting since upper casting is done implicitly.

mais en cas de += cela fonctionne très bien parce que l'opérateur fait implicitement le type de conversion du type de variable right au type de variable left, donc pas besoin de lancer explicitement.


85
2018-01-03 10:15



Le problème ici implique la coulée de type.

Lorsque vous ajoutez int et long,

  1. L'objet int est moulé à long et les deux sont ajoutés et vous obtenez un objet long.
  2. mais un objet long ne peut pas être implicitement casté en int. Donc, vous devez le faire explicitement.

Mais += est codé de telle façon qu'il ne lance que le type. i=(int)(i+m)


56
2018-01-03 10:20



Dans Java, les conversions de type sont effectuées automatiquement lorsque le type de l'expression sur le côté droit d'une opération d'affectation peut être promu en toute sécurité au type de la variable sur le côté gauche de l'affectation. Ainsi, nous pouvons assigner en toute sécurité:

 octet -> short -> int -> long -> float -> double. 

La même chose ne fonctionnera pas dans l'autre sens. Par exemple, nous ne pouvons pas convertir automatiquement un long en un entier, car le premier nécessite plus de stockage que le second et, par conséquent, des informations peuvent être perdues. Pour forcer une telle conversion, nous devons effectuer une conversion explicite.
Type - Conversion


47
2018-01-23 05:50



Parfois, une telle question peut être posée lors d'une interview.

Par exemple, lorsque vous écrivez:

int a = 2;
long b = 3;
a = a + b;

il n'y a pas de typecasting automatique. En C ++ il n'y aura pas d'erreur compilant le code ci-dessus, mais en Java vous obtiendrez quelque chose comme Incompatible type exception.

Donc, pour l'éviter, vous devez écrire votre code comme ceci:

int a = 2;
long b = 3;
a += b;// No compilation error or any exception due to the auto typecasting

37
2017-12-02 10:40



La principale différence est que a = a + b, il n'y a pas de dactylographie en cours, et donc le compilateur se met en colère contre vous pour ne pas typer. Mais avec a += b, ce qu'il fait vraiment, c'est typer b à un type compatible avec a. Donc si vous faites

int a=5;
long b=10;
a+=b;
System.out.println(a);

Ce que vous faites vraiment est:

int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);

18
2018-06-07 23:27



Point subtil ici ...

Il y a un modèle implicite pour i+j quand j est un double et i est un int. Java TOUJOURS convertit un entier en double lorsqu'il y a une opération entre eux.

Clarifier i+=j où i est un nombre entier et j est un double peut être décrit comme

i = <int>(<double>i + j)

Voir: cette description de la coulée implicite

Vous pourriez vouloir classer j à (int) dans ce cas pour plus de clarté.


7
2018-01-18 20:07