Jusqu'à aujourd'hui, je pensais que par exemple:
i += j;
Était juste un raccourci pour:
i = i + j;
Mais si nous essayons ceci:
int i = 5;
long j = 8;
Alors i = i + j;
ne compilera pas mais i += j;
compilera bien.
Cela signifie-t-il qu'il s'agit en fait d' i += j;
un raccourci pour quelque chose comme ça
i = (type of i) (i + j)
?
java
casting
operators
variable-assignment
assignment-operator
Honza Brabec
la source
la source
i+=(long)j;
même compilera bien.i += (int) f;
jette f avant l'addition, donc ce n'est pas équivalent.(int) i += f;
jette le résultat après l'affectation, pas équivalent non plus. il n'y aurait pas de place pour placer une conversion qui signifierait que vous souhaitez convertir la valeur après l'ajout, mais avant l'affectation.Réponses:
Comme toujours avec ces questions, le JLS détient la réponse. Dans ce cas, §15.26.2 Opérateurs d'affectation composée . Un extrait:
Un exemple cité du §15.26.2
En d'autres termes, votre hypothèse est correcte.
la source
i+=j
Compile donc comme je l'ai vérifié moi-même, mais cela entraînerait une perte de précision non? Si tel est le cas, pourquoi ne permet-il pas que cela se produise également dans i = i + j? Pourquoi nous déranger là-bas?i += j
), il est plus sûr de supposer que la perte de précision est souhaitée par opposition à l'autre (i = i + j
)E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))
c'est un peu comme la conversion de type implicite vers le bas (de long en entier). Alors que dans i = i + j, nous devons le faire explicitement, c'est-à-dire fournir la(T)
partie dansE1 = ((E1) op (E2))
N'est-ce pas?Un bon exemple de ce casting utilise * = ou / =
ou
ou
ou
la source
A
;)ch += 32
= DTrès bonne question. La spécification du langage Java confirme votre suggestion.
la source
double->float
comme un élargissement, étant donné que les valeurs de typefloat
identifient les nombres réels de manière moins spécifique que celles de typedouble
. Si l'on considèredouble
comme une adresse postale complète etfloat
comme un code postal à 5 chiffres, il est possible de satisfaire une demande de code postal à partir d'une adresse complète, mais il n'est pas possible de spécifier avec précision une demande d'adresse complète à l'aide d'un seul code postal . Convertir une adressefloat->double
équivaut à convertir le code postal américain 90210 avec "US Post Office, Beverly Hills CA 90210".Oui,
essentiellement quand on écrit
le compilateur convertit cela en
Je viens de vérifier le
.class
code du fichier.Vraiment une bonne chose à savoir
la source
vous devez convertir de
long
àint
explicitly
dans le cas oùi = i + l
il compilera et donnera une sortie correcte. commeou
mais dans ce cas,
+=
cela fonctionne très bien, car l'opérateur effectue implicitement le transtypage de type de variable droite en type de variable gauche, il n'est donc pas nécessaire de transtyper explicitement.la source
int
est effectué après le+
. Le compilateur (devrait?) Jeter un avertissement si elle avait vraiment jeté l'long
àint
.Le problème ici concerne la conversion de type.
Lorsque vous ajoutez int et long,
Mais il
+=
est codé de telle manière qu'il tape du casting.i=(int)(i+m)
la source
En 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 sans risque attribuer:
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
la source
long
est 2 fois plus grand quefloat
.float
ne peut pas contenir toutes lesint
valeurs possibles et undouble
ne peut pas contenir toutes leslong
valeurs possibles .double d=33333333+1.0f;
sans se plaindre, même si le résultat 33333332.0 ne serait probablement pas ce qui était prévu (incidemment, la réponse arithmétiquement correcte de 33333334.0f serait représentable comme l'unfloat
ou l' autreint
).Parfois, une telle question peut être posée lors d'un entretien.
Par exemple, lorsque vous écrivez:
il n'y a pas de transtypage automatique. En C ++, il n'y aura pas d'erreur lors de la 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:
la source
op
utilisation en C ++ avec son utilisation en Java. J'aime toujours voir ces petites anecdotes et je pense qu'elles contribuent à la conversation qui peuvent souvent être laissées de côté.La principale différence est qu'avec
a = a + b
, il n'y a pas de transtypage en cours, et donc le compilateur se fâche contre vous pour ne pas transtyper. Mais aveca += b
, ce qu'il fait vraiment, c'est la conversionb
en un type compatible aveca
. Donc si tu le faisCe que vous faites vraiment, c'est:
la source
Point subtil ici ...
Il y a un transtypage implicite pour
i+j
quandj
est un double eti
est un int. Java convertit TOUJOURS un entier en double lorsqu'il y a une opération entre eux.Pour clarifier
i+=j
oùi
est un entier etj
est un double peut être décrit commeVoir: cette description du casting implicite
Vous voudrez peut - être cataloguée
j
à(int)
dans ce cas pour plus de clarté.la source
int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. Ajout de zéro àsomeInt
ne devrait affecter sa valeur, mais la promotionsomeInt
defloat
peut changer sa valeur.La spécification du langage Java définit
E1 op= E2
comme équivalent àE1 = (T) ((E1) op (E2))
oùT
est un type deE1
etE1
est évaluée une fois .C'est une réponse technique, mais vous vous demandez peut-être pourquoi c'est un cas. Eh bien, considérons le programme suivant.
Qu'est-ce que ce programme imprime?
Avez-vous deviné 3? Dommage, ce programme ne se compilera pas. Pourquoi? Eh bien, il se trouve que l'ajout d'octets en Java est défini pour renvoyer un
int
. Je pense que cela est dû au fait que la machine virtuelle Java ne définit pas d'opérations d'octets pour économiser sur les bytecodes (il y en a un nombre limité, après tout), l'utilisation d'opérations entières à la place est un détail d'implémentation exposé dans un langage.Mais si
a = a + b
cela ne fonctionne pas, cela signifieraita += b
qu'il ne fonctionnerait jamais pour les octets s'ilE1 += E2
était défini comme telE1 = E1 + E2
. Comme le montre l'exemple précédent, ce serait effectivement le cas. En tant que hack pour faire+=
fonctionner l'opérateur pour les octets et les courts métrages, il y a une distribution implicite impliquée. Ce n'est pas un hack génial, mais au cours du travail Java 1.0, l'accent était mis sur la sortie du langage pour commencer. Maintenant, en raison de la compatibilité descendante, ce hack introduit dans Java 1.0 n'a pas pu être supprimé.la source