![]() |
Mon site perso a changé d'adresse. Si rien ne se passe cliquez sur le lien ci-dessus. |
|
|
|
|
|
|
Développons en Java v 0.85 béta | |
| Copyright (C) 1999-2005 Jean-Michel DOUDOUX |
![]() |
![]() |
La version 1.5 de Java dont le nom de code est Tiger est développée par la JSR 176.
La version utilisée dans ce chapitre est la version bêta 1.
| Exemple : |
|
La version 1.5 de Java apporte de nombreuses évolutions qui peuvent être classées dans deux catégories :
Ce chapitre va détailler les nombreuses évolutions sur la syntaxe du langage.
Depuis sa première version et jusqu'à sa version 1.5, le langage Java lui-même n'a que très peu évolué : la version 1.1 a ajouté les classes internes et la version 1.4 les assertions.
Les évolutions de ces différentes versions concernaient donc essentiellement les API de la bibliothèque standard (core) de Java.
La version 1.5 peut être considérée comme une petite révolution pour Java car elle apporte énormément d'améliorations sur le langage. Toutes ces évolutions sont déjà présentes dans différents autres langages notamment C#.
Le but principal de ces ajouts est de faciliter le développement d'applications avec Java en simplifiant l'écriture et la lecture du code.
Un code utilisant les nouvelles fonctionnalités de Java 1.5 ne pourra pas être exécuté dans une version antérieure de la JVM.
Pour compiler des classes utilisant les nouvelles fonctionnalités de la version 1.5, il faut utiliser les options -target 1.5 et -source 1.5 de l'outil javac. Par défaut, ce compilateur utilise les spécifications 1.4 de la plate-forme.
L'autoboxing permet de transformer automatiquement une variable de type primitif en un objet du type du wrapper correspondant. L'unboxing est l'opération inverse. Cette nouvelle fonctionnalité est spécifiée dans la JSR 201.
Par exemple, jusqu'à la version 1.4 de Java pour ajouter des entiers dans une collection, il est nécessaire d'encapsuler chaque valeur dans un objet de type Integer.
| Exemple : |
|
Avec la version 1.5, l'encapsulation de la valeur dans un objet n'est plus obligatoire car elle sera réalisée automatiquement par le compilateur.
| Exemple (java 1.5): |
|
Jusqu'à la version 1.4 de Java, pour utiliser un membre statique d'une classe, il faut obligatoirement préfixer ce membre par le nom de la classe qui le contient.
Par exemple, pour utiliser la constante Pi définie dans la classe java.lang.Math, il est nécessaire d'utiliser Math.PI
| Exemple : |
|
Java 1.5 propose une solution pour réduire le code à écrire concernant les membres statiques en proposant une nouvelle fonctionnalité concernant l'importation de package : l'import statique (static import).
Ce nouveau concept permet d'appliquer les mêmes règles aux membres statiques qu'aux classes et interfaces pour l'importation classique.
Cette nouvelle fonctionnalité est développée dans la JSR 201. Elle s'utilise comme une importation classique en ajoutant le mot clé static.
| Exemple (java 1.5): |
|
L'utilisation de l'importation statique s'applique à tous les membres statiques : constantes et méthodes statiques de l'élément importé.
Cette nouvelle fonctionnalité est spécifiée dans la JSR 175.
Elle propose de standardiser l'ajout d'annotations dans le code. Ces annotations pourront ensuite être traitées par des outils pour générer d'autres éléments tel que des fichiers de configuration ou du code source.
Ces annotations concernent les classes, les méthodes et les champs. Leurs syntaxes utilisent le caractère « @ ».
Cette nouvelle fonctionnalité va permettre de passer un nombre non défini d'arguments d'un même type à une méthode. Ceci va éviter de devoir encapsuler ces données dans une collection.
Cette nouvelle fonctionnalité est spécifiée dans la JSR 201. Elle implique une nouvelle notation pour préciser la répétition d'un type d'argument. Cette nouvelle notation utilise trois petits points : ...
| Exemple (java 1.5): |
|
| Résultat : |
|
L'utilisation de la notation ... permet le passage d'un nombre indéfini de paramètres du type précisé. Tous ces paramètres sont traités comme un tableau : il est d'ailleurs possible de fournir les valeurs sous la forme d'un tableau.
| Exemple (java 1.5): |
|
| Résultat : |
|
Il n'est cependant pas possible de mixer des éléments unitaires et un tableau dans la liste des éléments fournis en paramètres.
| Exemple (java 1.5): |
|
| Résultat : |
|
Les generics permettent d'accroître la lisibilité du code et surtout de renforcer la sécurité du code grâce à un renforcement du typage. Ils permettent de préciser explicitement le type d'un objet et rendent le cast vers ce type implicite. Cette nouvelle fonctionnalité est spécifiée dans la JSR 14.
Ils permettent par exemple de spécifier quel type d'objets une collection peut contenir et ainsi éviter l'utilisation d'un cast pour obtenir un élément de la collection.
L'inconvénient majeur du cast est que celui-ci ne peut être vérifié qu'à l'exécution et qu'il peut échouer. Avec l'utilisation des generics, le compilateur pourra réaliser cette vérification lors de la phase de compilation : la sécurité du code est ainsi renforcée.
| Exemple (java 1.5): |
|
L'utilisation des generics va permettre au compilateur de faire la vérification au moment de la compilation est de s'assurer ainsi qu'elle s'exécutera correctement. Ce mécanisme permet de s'assurer que les objets contenus dans la collection seront homogènes.
La syntaxe pour mettre en oeuvre les generics utilise les symboles < et > pour préciser le ou les types des objets à utiliser. Seuls des objets peuvent être utilisés avec les generics : si un type primitif est utilisé dans les generics, une erreur de type « unexpected type » est générée lors de la compilation.
| Exemple (java 1.5): |
|
Si un objet de type différent de celui déclaré dans le generics est utilisé dans le code, le compilateur émet une erreur lors de la compilation.
| Exemple (java 1.5): |
|
| Résultat : |
|
L'utilisation des generics permet de rendre le code plus lisible et plus sûre notamment car il n'est plus nécessaire d'utiliser un cast et de définir une variable intermédiaire.
Les generics peuvent être utilisés avec trois éléments :
Pour définir une classe utilisant les generics, il suffit de déclarer leur utilisation dans la signature de la classe à l'aide des caractères < et >. Ce type de déclaration est appelé type paramétré (parameterized type) Dans ce cas, les paramètres fournis dans la déclaration du generics sont des variables de types. Si la déclaration possède plusieurs variables de type alors il faut les séparer par un caractère virgule.
| Exemple (java 1.5): |
|
Lors de l'utilisation de la classe, il faut utiliser les types paramétrés pour indiquer le type des objets à utiliser.
| Exemple (java 1.5): |
|
Le principe est identique avec les interfaces.
La syntaxe utilisant les caractères < et > se situe toujours après l'entité qu'elle concerne
| Exemple (java 1.5): |
|
Même le cast peut être utilisé avec le generics en utilisant le nom du type paramétré dans le cast.
Il est possible de préciser une relation entre une variable de type et une classe ou interface : ainsi il sera possible d'utiliser une instance du type paramétré avec n'importe quel objet qui hérite ou implémente la classe ou l'interface précisée avec le mot clé extend dans la variable de type.
| Exemple (java 1.5): |
|
L'utilisation du type paramétré MaClasseGeneric2 peut être réalisée avec n'importe quelle classe qui hérite de l'interface java.util.Collection.
| Exemple (java 1.5): |
|
Ce mécanisme permet une utilisation un peu moins strict du typage dans les generics.
L'utilisation d'une classe qui n'hérite pas de la classe où n'implémente pas l'interface définie dans la variable de type, provoque une erreur à la compilation.
| Exemple (java 1.5): |
|
L'itération sur les éléments d'une collection est fastidieuse avec la déclaration d'un objet de type Iterator.
| Exemple : |
|
La nouvelle forme de l'instruction for, spécifiée dans la JSR 201, permet de simplifier l'écriture du code pour réaliser une telle itération et laisse le soin au compilateur de générer le code nécessaire.
| Exemple (java 1.5): |
|
L'utilisation de la nouvelle syntaxe de l'instruction for peut être renforcée en combinaison avec les generics, ce qui évite l'utilisation d'un cast.
| Exemple (java 1.5): |
|
La nouvelle syntaxe de l'instruction peut aussi être utilisée pour parcourir tous les éléments d'un tableau.
| Exemple (java 1.5): |
|
L'exemple précédent fait aussi usage d'une autre nouvelle fonctionnalité du JDK 1.5 : l'unboxing.
Cela permet d'éviter la déclaration et la gestion dans le code d'une variable contenant l'index courant lors du parcours du tableau.
Souvent lors de l'écriture de code, il est utile de pouvoir définir un ensemble fini de valeurs pour une donnée pour par exemple définir les valeurs possibles qui vont caractériser l'état de cette donnée.
Pour cela, le type enum permet de définir un ensemble de constantes. Cette fonctionnalité existe déjà dans les langages C et Delphi entre autre.
Cette nouvelle fonctionnalité est spécifiée dans la JSR 201.
Jusqu'à la version 1.4, la façon la plus pratique pour palier au manque du type enum était de créer des constantes dans une classe.
| Exemple (java 1.5): |
|
Le principal inconvénient de cette technique est qu'il n'y a pas de contrôle sur la valeur affectée à une donnée surtout si les constantes ne sont pas utilisées.
La version 1.5 propose une fonctionnalité pour déclarer et utiliser un type enumération qui repose sur trois éléments :
| Exemple (java 1.5): |
|
A la rencontre de mot clé enum, le compilateur va automatiquement créer une classe possédant les caractéristiques suivantes :
Il est possible d'utiliser toutes ces caractéristiques.
| Exemple (java 1.5): |
|
| Résultat : |
|
Lors de la compilation de cet exemple, une classe interne est créée pour encapsuler l'énumération.
Pour pouvoir utiliser facilement une énumération, il est possible de la définir comme une entité indépendante.
| Exemple (java 1.5) : le fichier MonStyle.java |
|
Une fois définie, il est possible d'utiliser l'énumération simplement en définissant une variable du type de l'énumération
| Exemple (java 1.5): |
|
Les énumérations étant transformées en une classe par le compilateur, il y a une vérification de type faite de l'utilisation de l'énumération à la compilation.
La classe générée possède les caractéristiques suivantes :
L'instruction switch a été modifiée pour permettre de l'utiliser avec une énumération puisque bien qu'étant physiquement une classe, celle-ci possède une liste finie de valeurs associées.
Remarque : dans les différents cas de l'instruction switch, il n'est pas utile de préfixer chaque valeur de l'énumération utilisée par le nom de l'énumération puisque celle ci est automatiquement déterminée par le compilateur à partir de la variable passée en paramètre de l'instruction switch.| Exemple (java 1.5): |
|
| Résultat : |
|
Il est possible d'associer une énumération avec un objet dans une collection de type Map en utilisant la classe EnumMap avec les generics
| Exemple (java 1.5): |
|
| Résultat: |
|
|
|
|
|
|
|
Développons en Java v 0.85 béta | ||
| Copyright (C) 1999-2005 Jean-Michel DOUDOUX |