Pourquoi ne pas Java +=, -=, *=, /= composé des opérateurs d'affectation nécessite casting?
Jusqu'à aujourd'hui, j'ai pensé que pour exemple:
i += j;
Était juste un raccourci pour:
i = i + j;
Mais si nous essayons ceci:
int i = 5;
long j = 8;
Puis i = i + j;
ne compile pas mais i += j;
compiler amende.
Veut-il dire qu'en fait i += j;
est un raccourci pour quelque chose comme cela
i = (type of i) (i + j)
?
Je suis surpris de Java permet cela, en étant un langage plus stricte que celle de ses prédécesseurs. Les erreurs de casting peut conduire à un échec critique, comme ce fut le cas avec Ariane5 Vol 501 où un 64-bit à virgule flottante en fonte pour un entier 16 bits entraîné dans la chute.
Dans un système de contrôle de vol, écrit en Java, ce serait le cadet de vos soucis @SQLDiver
En fait
La constante pousser par un ensemble de développeurs pour plus de précision et un autre pour la facilité d'utilisation est vraiment intéressant. On a presque besoin de deux versions de la langue, qui est incroyablement précis et qui est facile à utiliser. Poussant Java à partir de deux directions se déplace vers inapproprié pour les deux groupes.
si elle n'a besoin de la coulée, où placeriez-vous?
Dans un système de contrôle de vol, écrit en Java, ce serait le cadet de vos soucis @SQLDiver
En fait
i+=(long)j;
même de compiler amende.La constante pousser par un ensemble de développeurs pour plus de précision et un autre pour la facilité d'utilisation est vraiment intéressant. On a presque besoin de deux versions de la langue, qui est incroyablement précis et qui est facile à utiliser. Poussant Java à partir de deux directions se déplace vers inapproprié pour les deux groupes.
si elle n'a besoin de la coulée, où placeriez-vous?
i += (int) f;
jette f avant l'addition, il n'est donc pas équivalent. (int) i += f;
convertit le résultat après la cession, ne sont pas équivalentes. il n'y aurait pas de place pour mettre un plâtre qui signifie que vous voulez jeter de la valeur après l'ajout, mais avant la cession.OriginalL'auteur Honza Brabec | 2012-01-03
Vous devez vous connecter pour publier un commentaire.
Comme toujours avec ces questions, le JLS détient la réponse. Dans ce cas §15.26.2 Composé Des Opérateurs D'Affectation. Un extrait:
Un exemple cité à partir de §15.26.2
En d'autres termes, votre hypothèse est correcte.
i+=j
compile comme je l'ai vérifié moi-même, mais il entraînerait une perte de la précision? Si c'est le cas, pourquoi ne pas lui permettre de se produire dans i=i+j aussi? Pourquoi bug-nous là?Je devine que la langue concepteurs pensent que, dans un cas (
i += j
), il est plus sûr de supposer que la perte de précision est souhaitée car contrairement aux autres cas (i = i + j
)Non, juste là, en face de moi! Désolé, je n'ai pas le remarquer plus tôt. Comme dans votre réponse,
E1 op= E2 is equivalent to E1 = (T)((E1) op (E2))
, c'est un peu comme implicite bas typecasting (long int). Alors que dans i = i+j, nous devons le faire de manière explicite, c'est à dire, de fournir les(T)
partie dansE1 = ((E1) op (E2))
N'est-ce pas?Je suppose que ce est utilisé pour éviter un cast explicite et/ou
f
postfix dans la situation de l'ajout d'un double littérale à une courte?Une raison probable pour laquelle le compilateur Java ajoute un transtypage est parce que si vous êtes essayé de faire de l'arithmétique sur des types incompatibles, il n'existe aucun moyen d'effectuer un transtypage du résultat à l'aide de la forme contractée. Un transtypage de la résultat est généralement plus précis que le transtypage de la problématique de l'argument. Pas de transtypage ferait de la contraction inutile lors de l'utilisation de types incompatibles, comme il le ferait toujours provoquer le compilateur pour générer une erreur.
OriginalL'auteur Lukas Eder
Un bon exemple de ce casting est à l'aide de *=, /=
ou
ou
ou
ch est un char. 65 * 1.5 = 97.5 -> vous l'avez?
Ouais, mais je peux juste voir quelques débutants de venir ici, de cette lecture, et s'en va penser que vous pouvez convertir n'importe quel personnage de majuscules en minuscules en le multipliant par 1.5.
N'importe quel caractère tant qu'il est
A
😉Je vais vous révéler votre secret-
ch += 32
=DOriginalL'auteur Peter Lawrey
Très bonne question. Le Java Langage de spécification confirme votre suggestion.
ce que la ruse est-ce? Un élargissement de conversion qui est incorrecte arrondie, suivie d'un ajout qui ne fait pas changer le résultat, de la conversion en int pour produire un résultat qui est plus inattendu normal de l'esprit humain.
À mon humble avis, les règles de conversion aurais traité
double->float
que l'élargissement, sur la base des valeurs de typefloat
identifier les nombres réels moins précisément que ceux de typedouble
. Si l'on considèredouble
comme une adresse postale complète, etfloat
5-digit code postal, il est possible de satisfaire une demande pour un code postal donné une adresse complète, mais il n'est pas possible de spécifier exactement, une demande pour une adresse complète donné juste un code postal. Conversion d'une adresse à un code postal est une perte de fonctionnement, mais......quelqu'un qui a besoin d'une adresse complète ne serait pas généralement demandent un code postal. La Conversion de
float->double
est équivalent à la conversion de l'US postal, code 90210 avec "US Post Office, Beverly Hills, CA 90210".OriginalL'auteur Thirler
Oui,
essentiellement lorsque nous écrire
le compilateur convertit à
Je viens de vérifier le
.class
fichier de code.Vraiment une bonne chose à savoir
ce que vous entendez par fichier de classe? si vous poser des questions sur le fichier de la classe je l'ai mentionné dans mon post que c'est le respecté la version de votre classe java
Oh, vous avez parlé de "la" classe code de fichier, ce qui m'a amené à croire spécifique classfile a été impliqué. Je comprends ce que tu veux dire maintenant.
De toutes les lettres, vous avez réellement choisi "l" (L minuscule)...
Je suis en désaccord que l'on doit compter sur la police de distinguer dans ces cas-là... mais tout le monde a la liberté de choisir ce qui pense est le meilleur.
OriginalL'auteur Umesh Awasthi
vous avez besoin de jeter de
long
àint
explicitly
en cas dei = i + l
puis de compiler et de donner les bons de sortie. commeou
mais dans le cas de
+=
ça marche bien parce que l'opérateur implicitement le type coulée de type de droit de la variable de type de gauche de la variable n'a pas besoin de cast explicite.int
est effectuée après le+
. Le compilateur pourrait (devrait?) lancer un avertissement si il a vraiment coulé de l'long
àint
.OriginalL'auteur dku.rajkumar
Le problème ici implique la conversion de type.
Lorsque vous ajoutez int et long,
Mais
+=
est codé de telle façon qu'il ne la conversion de type.i=(int)(i+m)
OriginalL'auteur Dinesh Sachdev 108
En Java le type de conversions sont effectuées automatiquement lorsque le type de l'expression sur le côté droit d'une opération d'affectation peut être en toute sécurité promu le type de la variable sur le côté gauche de la cession. Ainsi, nous pouvons en toute sécurité attribuer:
La même volonté de ne pas fonctionner dans l'autre sens. Par exemple on ne peut pas convertir automatiquement un long int, parce que la première nécessite plus d'espace de stockage que la seconde et, par conséquent, des informations peuvent être perdues. Pour forcer la conversion, nous devons effectuer une conversion explicite.
De Conversion De Type
long
est 2 fois plus grande quefloat
.Un
float
ne pouvez pas tenir toutint
valeur, et undouble
ne pouvez pas tenir toutlong
valeur.Qu'entendez-vous par "en toute sécurité converti" ? À partir de la dernière partie de la réponse que je peux en déduire que vous avez voulu dire automatique de conversion ( cast implicite ) qui n'est bien sûr pas vrai dans le cas de float -> long. float pi = 3.14 f; long b = pi; entraînera une erreur de compilation.
Vous seriez mieux de différenciation à virgule flottante de type primitif avec un entier de type primitif. Ils ne sont pas la même chose.
Java est simpliste des règles de conversion qui nécessitent l'utilisation de jette dans de nombreux modèles où les comportements jette serait contraire à la hauteur des attentes, mais ne nécessite pas de castes de nombreux modèles qui sont généralement erronée. Par exemple, un compilateur acceptera
double d=33333333+1.0f;
sans plainte, même si le résultat 33333332.0 il ne serait probablement pas ce qui était prévu (d'ailleurs, les arithmétiquement-réponse correcte de 33333334.0 f serait représentable commefloat
ouint
).OriginalL'auteur tinker_fairy
Parfois, une telle question peut être posée lors d'une entrevue.
Par exemple, lorsque vous écrivez:
n'est pas automatique typecasting. En C++ il n'y aura aucune erreur à la compilation le code ci-dessus, mais en Java, vous obtiendrez quelque chose comme
Incompatible type exception
.Donc, pour éviter cela, vous devez écrire du code comme ceci:
op
utiliser en C++ pour son utilisation en Java. J'ai toujours envie de voir ces bits de trivia et je pense qu'ils apportent quelque chose à la conversation qui peut souvent être laissé de côté.Cependant la question elle-même est intéressant, demandant à ce dans une interview est stupide. Cela ne prouve pas que la personne peut produire un code de bonne qualité - cela prouve qu'il avait assez de patience pour préparer un Oracle certificat d'examen. Et à "éviter" les incompatible types à l'aide d'un dangereux d'auto-conversion, et ainsi cacher la possible erreur de dépassement de capacité, probablement même prouve que la personne n'est pas en mesure de produire probable d'un code de bonne qualité. Putain la Java des auteurs de tous ces auto-conversions et de l'auto-boxing et tous!
OriginalL'auteur Stopfan
La principale différence est que, avec
a = a + b
, il n'y a pas de typecasting et donc le compilateur se met en colère contre vous pour ne pas typecasting. Mais aveca += b
, de quoi il est vraiment en train de faire est typecastingb
à un type compatible aveca
. Donc, si vous neCe que vous êtes vraiment en train de faire est:
OriginalL'auteur takra
Point subtil ici...
Il y a un transtypage implicite pour
i+j
quandj
est un double eti
est un int.Java TOUJOURS convertit un entier en une double quand il y a une opération entre eux.
De clarifier
i+=j
oùi
est un entier etj
est un double peut être décrit commeVoir: cette description de la conversion implicite
Vous pourriez transtypage
j
à(int)
dans ce cas, pour plus de clarté.int someInt = 16777217; float someFloat = 0.0f; someInt += someFloat;
. L'ajout de zéro àsomeInt
ne devrait pas affecter sa valeur, mais la promotion desomeInt
àfloat
peut modifier sa valeur.OriginalL'auteur Gabe Nones
Java Language Specification définit
E1 op= E2
est équivalent àE1 = (T) ((E1), op (E2))
T
est de typeE1
etE1
est évaluée une fois.C'est une réponse technique, mais vous vous demandez peut-être pourquoi c'est un cas. Ainsi, considérons le programme suivant.
Ce que ce programme ne fait imprimer?
Avez-vous deviné 3? Tant pis, ce programme ne compile pas. Pourquoi? Eh bien, il arrive que l'ajout d'octets en Java est défini pour renvoyer un
int
. Cela, je crois que c'était parce que la Machine Virtuelle Java n'est pas de définir octet opérations à enregistrer sur bytecode (il y a un nombre limité de personnes, après tout), en utilisant les opérations sur entiers au lieu de cela est un détail d'implémentation exposés dans une langue.Mais si
a = a + b
ne fonctionne pas, cela voudrait direa += b
ne pourrais jamais travailler pour les octets si ilE1 += E2
a été défini pour êtreE1 = E1 + E2
. Comme l'exemple précédent le montre, ce serait en effet le cas. Comme un hack pour faire+=
travail d'opérateur pour les octets et shorts, il y a un cast implicite impliqués. Ce n'est pas que les grandes d'un hack, mais de retour au cours de la Java 1.0 travail, l'accent a été mis sur l'obtention de la langue libéré pour commencer. Maintenant, à cause de la compatibilité, ce hack introduit dans Java 1.0 ne pouvait pas être supprimé.OriginalL'auteur Konrad Borowski