Next: 13 Classes imbriquées
Up: Java: Le langage
Previous: 11 Tableaux et chaînes
Subsections
A revoir et compléter
Nous avons dit (4.1.3) que toute expression possède un type.
Ce type peut être déduit en examinant les constantes, les variables et
les méthodes qui figurent dans une expression. On peut être amené à
écrire des expressions dont le type n'est pas correct. Parmi ces
expressions ``incorrectes'', certaines sont des vraies erreurs et le
compilateurs se charge de le signaler par un message d'erreur à la
compilation. Mais il en existe d'autre pour lesquelles Java décide
d'effectuer automatiquement les conversions nécessaires (quand
cela est possible) pour rendre l'expression correcte.
Il existe plusieurs types de conversions :
- Les conversions effectuées à l'exécution. La conversion d'un
objet de la classe Object en un objet de la classe
Thread nécessite une vérification à l'exécution pour
s'assurer que l'objet référencé est bien un objet de la classe
Thread ou d'une de ses sous classes. Si ce n'est pas le
cas, une exception est déclenchée.
- Les conversions effectuées à la compilation. La conversion d'un
objet de la classe Thread en un objet de la classe
Object ne nécessite aucune vérification à l'exécution.
Cette conversion est toujours valide.
- Les conversions avec perte d'information. La conversion d'un
double en un long peut éventuellement conduire une
perte d'information.
- Les conversions sans perte d'information. La conversion d'un
int en long peut toujours se faire sans perte
d'information.
La conversion d'un type en lui même est permise. Ceci peut sembler
trivial voir inutile mais cela permet d'autoriser les opérations de
changement de type (cast) redondantes.
La seule conversion permise pour le type boolean est la
conversion vers le type boolean lui-même.
Il existe 19 conversions possibles dans cette catégorie :
- byte vers short, int, long,
float, ou double
- short vers int, long, float,
ou double
- char vers int, long, float,
ou double
- int vers long, float, ou
double
- long vers float ou double
- float vers double
La conversion d'un int ou long vers un float ou double peut conduire à
une perte d'information. La value approchée résultat est obtenu
choisissant le flottant le plus de l'entier (IEEE 754
round-to-nearest ).
Quant aux conversions des entiers (plus petit en taille) vers un autre
entier (plus grand en taille) se fait évidemment sans perte de
précision et en complétant les bits de poids fort à 0.
Toutes ces conversions ne produisent jamais d'exception lors de
l'exécution.
Il existe 23 conversions possibles dans cette catégorie :
- byte vers char
- short vers byte ou char
- char vers byte ou short
- int vers byte, short, ou char
- long vers byte, short, char, ou int
- float vers byte, short, char, int, ou long
- double vers byte, short, char, int,
long, ou float
Ces conversions peuvent évidemment conduire à des pertes
d'informations. Les conversions des entiers (plus grand en taille)
vers un autre entier (plus petit en taille) se fait en supprimant les
bits de poids fort.
Conversions
des flottants
vers des entiers
- Conversion d'un type de sous classe en un type d'une classe
ancêtre.
- Conversion d'un objet d'une classe implantant l'interface en un
objet de cette interface.
- Conversion du type null en n'importe type de classe, d'interface
ou tableau.
- Conversion d'un type de sous interface en un type d'une
interface ancêtre.
- Conversion d'un type interface en type Object.
- Conversion d'un tableau en type Object.
- Conversion d'un tableau en type Cloneable.
- Conversion d'un tableau d'objets SC[] en un tableau d'objets
TC[] à condition qu'il existe une conversion de même nature de SC
vers TC.
Toutes ces conversions ne produisent jamais d'exception lors de
l'exécution.
- Conversion d'un type de classe vers un type de sous classe.
- Conversion d'un type de classe S vers un type interface à
condition que S ne soit pas final et qu'il n'implante pas
l'interface.
- Conversion du type Object en un tableau.
- Conversion du type Object en une interface.
- Conversion du type interface en un type classe non
final.
- Conversion du type interface en un type classe final à
condition qu'il implante l'interface.
- Conversion du type interface I en un type interface J à
condition que I ne soit pas une sous interface de J et qu'il
n'existe pas de méthode de même signature et de type différent dans
I et J.
- Conversion d'un tableau d'objets SC[] en un tableau d'objets
TC[] à condition qu'il existe une conversion de même nature de SC
vers TC.
Toutes ces conversions effectue des test à l'exécution et peuvent
produire l'exception ClassCastException lors de l'exécution.
IL y a une conversion d'un type quelconque (même le type
null) en type String.
Il n'est pas permis de convertir
- un objet en type primitif.
- un type primitif en objet sauf pour les String.
- le type null en type primitif.
- le type null en autre que lui même.
- en type boolean qu'un autre type boolean.
- le type boolean en autre que lui même ou en
String
- un type de classe en un autre type de classe qui ne soit pas une
sous classe ou classe ancêtre.
- un type de classe en un type interface si la classe est
final et qu'elle n'implante pas cette interface.
- un type de classe (autre que Object) en un type
tableau.
- un type interface en type classe (autre que String) si
cette dernière est final et qu'elle n'implante pas cette
interface.
- un type interface en type interface si dans ces deux interfaces
il n'existe pas de méthode de même signature et de type différent.
- un type tableau en un type de classe autre que String
ou Object.
- un type tableau en un type interface autre que
Cloneable
- le type SC[] en type TC[] si la conversion de Sc en TC est
interdite.
Lors d'une affectation, le type de l'opérande droit est converti en
le type de l'opérande gauche.
Array Store Exception
L'affectation
est valide car la constante 5 (qui est de type int) est converti
automatiquement en byte. Il n'est pas nécessaire d'écrire
Lorsque la conversion requise pour une affectation est interdite
alors une erreur de compilation est générée.
Lors de l'invocation d'une méthode, les paramètres effectifs de la
méthode sont convertis en accord avec le type des paramètres formels.
Contrairement à l'affectation, la conversion vers un type plus
restreint n'est pas effectuée et ce pour simplifier la surcharge des
méthodes :
class Test {
static int m(byte a, int b) { return a+b; }
static int m(short a, short b) { return a-b; }
public static void main(String[] args) {
System.out.println(m(12, 2)); // Erreur de compilation
}
}
|
La conversion de chaînes de caractères ne concerne que l'opérateur de
concaténation ``+''.
N'importe quel type peut être converti en String. Pour être
converti en un objet de type String, une valeur d'un type
primitif est tout d'abord converti en un objet de son type (par
exemple, un float en un objet de type Float). Ainsi, on se ramène au
cas général de la conversion d'un objet d'un classe en un objet de
type String qui utilise la méthode toString.
Le changement de type s'obtient en appliquant explicitement
l'opération de cast . Par cette opération, il est permis
d'effectuer n'importe quel opération de conversion permise.
Certaines conversions non permises peuvent être détectées à la
compilation et auquel cas, une erreur de compilation est générée.
détailler
voir spec
Dans le contexte d'opération arithmétiques, les conversions
automatiques effectuées sont appelées promotions numériques.
La promotion numérique sont effectuées dans les cas suivants:
Next: 13 Classes imbriquées
Up: Java: Le langage
Previous: 11 Tableaux et chaînes
Touraivane
6/12/1998