java: Auto-boxe et casting? [fermé]
Je suis confondu avec un petit problème, voir ce qui suit :
Double j = new Double(5); // No problem.
double j =5;//
//But
//Here the problem:
Double j = 5;
Long k =5;
Float g = 5.0;
Je connais la solution mais je veux comprendre pourquoi dans certaines situations le casting est fait implicitement et dans d'autres non.
4 answers
Il n'y a rien de mal à
Double j = new Double(5);
Parce que Java convertira 5
d'un int
en double
qu'un constructeur Double
prendra. Il convertira également le {[4] } en un double
pour la ligne:
double j =5;
C'est une conversion primitive croissante.
Il y a un problème avec ces lignes.
Double j = 5;
Long k =5;
Float g = 5.0;
Java n'effectuera pas une conversion primitive d'élargissement (5
en 5.0
ou 5L
) et une conversion de boxe (double
en Double
ou long
en Long
) implicitement. Il exécutera l'un ou l'autre implicitement, mais pas les deux. Il n'effectuera pas non plus de conversion primitive de rétrécissement ici (5.0
en 5.0f
).
Le JLS, Section 5.2 , stipule:
Les contextes d'affectation permettent l'utilisation de l'un des éléments suivants:
Une conversion identitaire(§5.1.1)
Une conversion primitive croissante(§5.1.2)
Une conversion de référence élargie(§5.1.5)
Une boxe conversion (§5.1.7) éventuellement suivie d'une conversion de référence
Une conversion de déballage (§5.1.8) éventuellement suivie d'une conversion primitive d'élargissement.
Il n'autorise pas explicitement ce que ces 3 dernières lignes tentent de faire: une conversion primitive élargie suivie d'une conversion de boxe.
Fait intéressant, Java permet:
Number x = 5; // boxing followed by widening
double y = new Integer(5); // unboxing followed by widening
Le problème avec ces trois affectations est que bien que Java ait des règles sur l'élargissement des conversions primitives en primitives, il n'a pas de règles pour les conversions primitives en wrapper. En d'autres termes, il n'y a pas de règle qui ferait une conversion en plus de l'auto-boxe.
Double j = 5; // 5 is an int literal. It can be auto-boxed only to Integer
Long k =5; // Same here
Float g = 5.0; // 5.0 is a double literal. It can be auto-boxed only to Double
Vous pouvez les corriger en ajoutant un suffixe approprié ou un casting approprié, comme ceci:
Double j = (double)5;
Long k = 5L;
Float g = (float)5.0;
Double j = nouveau Double (5); double k =j;
Ici unboxing est survenu. obtenir la valeur de l'objet Wrapper et affecter au type de données primitif (int, doulbe, float) double k= j; est équivalent à j. doubleValue (); le type de retour est double
Double j = 5;
Vous voulez utiliser ti comme ceci, Vous devez mentionner le type de données, Double a=(double)5; ou Double a= Double.valueOf (5);
C'est l'autoboxing. Sans connaître le type de données ne peut pas java cast, sinon vous devriez donner correct type de données primitif(5.0).
double d = 5;
// l'élargissement de
Dans l'instruction ci-dessus, l'élargissement se produit de la primitive int
à double
Double d = new Double(5);
// classe wrapper constructeur utilisé et transmis int
valeur de type 5, mais renvoie classe wrapper Double
référence d
, avec référence à la valeur de 5,0 comme jvm
ferons widening
sur int
valeur de type 5 et de retour double
type 5.0 utilisé par classe wrapper Double
constructor
.
Double d = 5.0;
// est-ce que la boxe automatique, c'est la même chose comme Double d = new Double(5);
Mais, Double d = 5;
// est erroné comme int
valeur de type 5 ne peut pas être auto boxed
à double
valeur de type et référencé par Double
type de variable de référence. jvm n'effectue pas un tel élargissement de type primitif pour les valeurs à référencer par la variable de référence de classe wrapper.