23/06/2010

Point théorique Java : Enchainements de conversion

Les enchainements de conversions autorisés lors d'une assignation, d'un passage de paramètre ou d'une opération sont :
graph.png
Légende :
// I = identity
// WP = Widening primitive
// WR = Widening reference
// B = Boxing
// U = Unboxing




Ainsi on peut écrire :

Number n = 4;		//(Boxing en Integer -> Widening reference)
Objet o = 4; //(id)
long l = (Integer)4; //(Unboxing -> de Widening primitive)


De la même facon
// même chose pour un passage de paramètre
MethodQuiAttendUnObject(4);
// même chose pour une opération
long l = ((Integer)4 + 7);


Mais on ne peut toujours pas écrire :
Long l = 4;	//(widening reference -> Boxing) est interdit


En pratique ces exemples semblent être les seuls cas intéressants.

(*) Identity est la conversion qui transforme un type en lui même.
Le fait que ce soit autorisé permet parfois de rendre le code plus lisible ex :
{
int quelquechose = 4;
... un grand nombre de lignes de code sans utiliser la variable quelquechose;
(int)quelquechose += 5;
}

Questions pièges Java n°5

Question 5 :
Dans le programme suivant quelles sont les lignes de codes qui génèrent une erreur de compilation :

class AClass {
public static void main() {
Byte B1 = 2;
Byte B2 = 200;
Long L = 2;
Number N = 2;
Object O = 2;
}
}

16/06/2010

Questions pièges Java n°5 : réponse

Code :

class AClass {
public static void main() {
Byte B1 = 2;
Byte B2 = 200;
Long L = 2;
Number N = 2;
Object O = 2;
}
}


Réponse
Les trois premières lignes du corps de la fonction main sont incorrectes

Explication
La première ligne est incorrecte car :
- on ne peut pas Boxer un int en Byte, on ne peut que le boxer en Integer
- il n'existe pas de conversion de Byte en Integer
- il n'existe pas d'enchainement de conversion implicite qui commençe par caster un int en byte puis qui le boxe en Byte

Ceci n'a rien à voir avec la valeur contenue dans le Byte. La ligne 4 est donc tout aussi incorrecte.

Cela n'a rien à voir non plus avec le fait que le byte soit plus "étroit" que le int. La ligne 5 est incorrecte pour exactement les mêmes raisons.

Les lignes 6 et 7 sont correctes. Il s'agit d'un enchainement de conversions :
- Boxing (int -> Integer)
- Widening reference (Integer ->Number) ou (Integer -> Object)


Point théorique associé
ici