Pourquoi pas Java?+=, -=, *=, /= les opérateurs de assignations composées ont besoin de casting?
Jusqu'à aujourd'hui, j'ai pensé que par exemple:
i += j;
N'était qu'un raccourci pour:
i = i + j;
Mais si nous essayons ceci:
int i = 5;
long j = 8;
puis i = i + j;
ne compilera pas mais i += j;
compilera fine.
veut-il dire qu'en fait i += j;
est un raccourci pour quelque chose comme cela
i = (type of i) (i + j)
?
10 réponses
comme toujours avec ces questions, le JLS détient la réponse. Dans ce cas §15.26.2 Assignment Operators . Un extrait:
une expression d'assignation composée de la forme
E1 op= E2
est équivalente àE1 = (T)((E1) op (E2))
, oùT
est le type deE1
, sauf queE1
est évalué une seule fois.
un exemple cité de §15.26.2
[...] le code suivant est correct:
short x = 3; x += 4.6;
et donne x ayant la valeur 7 parce qu'il est équivalent à:
short x = 3; x = (short)(x + 4.6);
En d'autres termes, votre hypothèse est correcte.
un bon exemple de cette coulée 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'
très bonne question. Le Java Language specification confirme votre suggestion.
par exemple, le code suivant est correct:
short x = 3; x += 4.6;
et donne x ayant la valeur 7 parce qu'il est équivalent à:
short x = 3; x = (short)(x + 4.6);
Oui,
en gros quand on écrit
i += l;
le compilateur convertit ceci en
i = (int)(i + l);
je viens de vérifier le code de fichier .class
.
Vraiment une bonne chose à savoir
vous devez lancer de long
à int
explicitly
dans le cas de i = i + l
alors il compilera et donnera la 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 dans le cas de +=
cela fonctionne très bien parce que l'opérateur fait implicitement le moulage de type de la variable de droite au type de la variable de gauche donc n'a pas besoin de mouler explicitement.
le problème ici concerne le moulage par type.
quand vous ajoutez int et long,
- l'objet int est moulé en long et les deux sont ajoutés et vous obtenez l'objet long.
- mais longtemps l'objet ne peut pas être implicitement coulé à l'int. Donc, vous avez à le faire explicitement.
mais +=
est codé de telle sorte qu'il ne type coulée. i=(int)(i+m)
en Java type conversions 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 attribuer en toute sécurité:
byte -> short -> int -> long -> float -> double.
cela ne marchera pas dans l'autre sens. Par exemple, nous ne pouvons pas convertir automatiquement un long en int parce que le premier nécessite plus de stockage que le second et par conséquent des informations peuvent être perdues. Pour forcer la conversion, nous devons effectuer une conversion explicite.
Conversion De Type
Parfois, une telle question peut être posée lors d'une entrevue.
par exemple, quand vous écrivez:
int a = 2;
long b = 3;
a = a + b;
il n'y a pas de typographie automatique. En C++ il n'y aura pas d'erreur de compilation du 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
la principale différence est qu'avec a = a + b
, il n'y a pas de typographie en cours, et donc le compilateur se fâche contre vous pour ne pas avoir fait de typographie. Mais avec a += b
, ce qu'il fait vraiment c'est la typographie 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 êtes vraiment en train de faire est:
int a=5;
long b=10;
a=a+(int)b;
System.out.println(a);
point subtil ici...
il y a un message type implicite pour i+j
quand j
est un double et i
est un int.
Java ALWAYS convertit un entier en un double lorsqu'il y a une opération entre eux.
clarifier i+=j
où i
est un entier et j
est un double peut être décrit comme
i = <int>(<double>i + j)
voir: ce description de la coulée implicite
vous pouvez taper j
à (int)
pour plus de clarté.