Algorithmique et langage Java

Transtypage

L'opérateur de transtypage (opérateur de "cast") permet de modifier explicitement le type d'une valeur avant de l'affecter à une variable ou de l'utiliser.

On écrit entre parenthèses le nom du nouveau type voulu, suivi de la valeur à transtyper, du nom de la variable contenant cette valeur, de l'opération fournissant cette valeur...

Il faut qu'il y ait compatibilité entre l'ancien et le nouveau type (qui doivent tous deux être des types primitifs).

Exemple : créer et exécuter la classe Transtyp 1

package initial;

public class Transtyp1 {

	public static void main(String[] args) {
		ConsoleTexte mc=new ConsoleTexte();
		mc.ecritLn(12.5/3);
		mc.ecritLn((int)12.5/3);

	}

}
Pour ces deux lignes d'instruction, qu'est-ce qui change dans le résultat, selon qu'on applique ou pas l'opérateur de cast ? De quel type est, dans chaque cas, le résultat final ?

Attention, l'opérateur de cast est prioritaire sur les opérateurs binaires.

Exemple : créer et exécuter la classe Transtyp2 :

package initial;
public class Transtyp2 {
	public static void main(String[] args) {
		ConsoleTexte mc=new ConsoleTexte();
		mc.ecritLn((float)10/3);
		mc.ecritLn((float)(10/3));
	}
}

Justifier le résultat obtenu pour chaque ligne d'instructions.

Les types numériques sont compatibles entre eux, et avec le type char. Par exemple créer et exécuter la classe Transtyp3

package initial;

public class Transtyp3 {

	public static void main(String[] args) {
		ConsoleTexte mc=new ConsoleTexte();
		mc.ecritLn(51);
		mc.ecritLn((char)51);
		mc.ecritLn('3');
		mc.ecritLn((int)'3');
		mc.ecritLn(165.0/3);
		mc.ecritLn((char)(165.0/3));

	}

}
La seconde ligne convertit 51, qui était à priori une valeur numérique de type entier int, en un type char : elle affiche 3 (c'est une façon d'obtenir un caractère à partir de son code Unicode).
La quatrième ligne convertit le caractère '3', à priori de type char, en son équivalent sous forme entière int, c'est à dire en son code Unicode, 51 (c'est une façon de connaître le code unicode d'un caractère).
La dernière ligne convertit le résultat de l'opération 165.0/3, qui est de type double , en un type char. Elle affiche donc 7, qui est le caractère dont le code Unicode est 55, résultat de la division de 165 par 3.

Le transtypage peut entraîner une perte d'information et le compilateur Java s'assurera que vous savez ce que vous faites s'il existe un risque. Par exemple, créez la classe suivante :

package initial;

public class Transtyp4 {

	public static void main(String[] args) {
	    double n1=3.0;
	    double n2=3;
		int n=3;
	    int n3=3.0;
	}
	
}
La ligne int n3=3.0; comporte une erreur signalée par une croix rouge dans la marge. Si vous placez la souris dessus, vous voyez apparaître le message "Type mismatch: cannot convert from double to int" et si vous cliquez Eclipse vous suggère deux correctifs possibles : caster en int ou changer le type de n3 en double.
En effet la valeur 3.0 est de type double, et comme un double occupe plus de place en mémoire qu'un int, le casting pourrait causer des dégâts. Le compilateur ne prend donc pas l'initiative de changer le format.
En revanche le compilateur ne voit pas d'inconvénient à la ligne double n2=3; bien que n2 soit un double et 3 un int car le format final est plus grand que le format initial.

Pour voir ce que peut entraîner un transtypage, modifiez la classe Transtyp4 ainsi :

 package initial;

public class Transtyp4 {

	public static void main(String[] args) {
	ConsoleTexte mc=new ConsoleTexte();
	mc.ecritLn("Donne moi un nombre (entier ou décimal) compris entre 33 et 127");
    double entree=mc.getValeur(); 
    mc.ecritLn("comme un réel double: "+ entree);
    mc.ecritLn("comme un entier sur 4 octets: "+(int)entree);
    mc.ecritLn("comme un entier sur un octet: "+(byte)entree);
    mc.ecritLn("comme un caractère, sur 2 octets: "+ (char) entree);
	}

}
L'instruction getValeur() permet ici de récupérer une valeur numérique fournie par l'utilisateur, dans un type double.
Ce nombre est ensuite soumis à différents castings.
Les valeurs limites 33 et 127 sont indicatives et peuvent être transgressées.
En dessous de 33, le transtypage en char ne donne rien car les caractères correspondants sont non affichables dans ce type de console (sauf 32 qui est le caractère d'espacement);
Au dessus de 127 (ou en dessous de -128), le transtypage en byte donnera des résultats inattendus car le nombre à caster est trop grand pour le type byte, tous les digits qui "dépassent" seront donc perdus ! Pour un type signé comme le byte, cela peut même entraîner un changement du signe !
On peut aussi faire "déborder" le type short avec des valeurs supérieures à 32767 (215-1) ou inférieures à -32768 (215).
Il en va de même pour le transtypage en char en dessous de 0 et au-dessus de 65535 ((216-1), mais ce sera moins visible.
A partir de quelle valeur le transtypage de double en int causerait-il un débordement ?

 
Licence Creative Commons
licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé
Auteur : Nathalie Bonnin
Professeur de Physique, Chimie, Informatique au lycée La Martinière Monplaisir (Lyon 8ème)
Contact :
nathalie.bonnin (chez) scientillula.net
Licence Creative Commons
La totalité du contenu du site Scientillula.net appartient à Nathalie Bonnin et est mise à disposition selon les termes de la licence Creative Commons Attribution - Pas d’Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé