
FAQ JavaConsultez toutes les FAQ
Nombre d'auteurs : 53, nombre de questions : 231, dernière mise à jour : 7 juin 2009
Sommaire→Le développement→Les warnings- [Java 5.0] Comment activer/désactiver les warnings avec javac ?
- [Java 5.0] finally : 'finally clause cannot complete normally'
- [Java 5.0] serial : 'serializable class Main has no definition of serialVersionUID'
- [Java 5.0] path : 'bad path element'
- fallthrough : 'possible fall-through into case'
- [Java 5.0] unchecked : 'uses unchecked or unsafe operations'
- deprecation : 'uses or overrides a deprecated API'
- [Java 5.0] Comment supprimer un warning en particulier ?
Le compilateur Java du JDK 5.0 apporte son lot de nouveaux warnings. Pour rappel, un warning est un message survenant à la compilation pour indiquer un problème potentiel, mais qui ne bloque pas le déroulement de la compilation. Il est toutefois conseillé de les corriger car cela peut poser des problèmes à l'exécution.
Toutefois, ces warnings ne sont pas tous affichés par défaut. Seul certains d'entre eux affichent une note pour signaler leurs présences, par exemple :
Note: Main.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Ce message nous indique le problème potentiel (l'utilisation d'une méthode dépréciée dans ce cas) ainsi que la voie à suivre pour obtenir plus de détails sur ce problème (recompiler avec l'option -Xlint:deprecation).
Le JDK 5.0 a introduit une nouvelle option dans le compilateur javac afin de gérer l'affichage ou non des warnings : l'option -Xlint. Utilisée seule, elle permet d'activer tous les warnings du compilateur :
javac -Xlint MaClasse.java
L'option -Xlint accepte également les paramètres suivant :
| Valeur | Description |
|---|---|
| all | Active tous les warnings. |
| deprecation | Active les warnings concernant les éléments dépréciés.
il s'agit du même comportement que l'option -deprecation qui
existait déjà dans les versions précédentes. (Voir deprecation : 'uses or overrides a deprecated API') |
| unchecked | Active tous les warnings relatifs à l'utilisation des types paramétrés. (Voir [Java 5.0] unchecked : 'uses unchecked or unsafe operations'). |
| fallthrough | Active la vérification des switch par le compilateur. (Voir fallthrough : 'possible fall-through into case'). |
| path | Active les vérifications des chemins. (Voir [Java 5.0] path : 'bad path element'). |
| serial | Active tous les warnings concernant le Serialization (serialVersionUID). (Voir [Java 5.0] serial : 'serializable class Main has no definition of serialVersionUID'). |
| finally | Active tous les warnings concernant les blocs finally incorrect. (Voir [Java 5.0] finally : 'finally clause cannot complete normally'). |
Plusieurs valeurs peuvent être utilisées en même temps en les séparant par des virgules. En précédant ces valeur par un tiret (-), on désactive le warning associé. Par Exemple :
javac -Xlint *.java
javac -Xlint:all *.java
javac -Xlint:deprecation,unchecked
javac -Xlint:all,-unchecked
Ce warning signale qu'un bloc finally ne se termine pas correctement. En effet, un bloc finally ne devrait pas contenir d'instruction return puisqu'il est appelé en cas d'Exception ou de return dans le bloc try correspondant, ce qui fait que l'instruction return éventuelle du bloc try sera ignorée.
Ainsi, si un bloc finally comporte le mot-clef return, il sera signalé par ce warning, par exemple :
Main.java:26: warning: [finally] finally clause cannot complete normally
Ce warning n'est actif qu'avec les options -Xlint ou -Xlint:finally de javac 5.0...
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Ce warning signale qu'une classe qui implémente l'interface java.io.Serializable
n'a pas définit de serialVersionUID. En effet, le serialVersionUID permet
d'affecter un numéro de version à la classe. Ce numéro doit normalement être changé
lorsqu'un champs non-transiant est ajouté ou supprimé de la classe. Théoriquement,
c'est au développeur de gérer ce numéro de version. Toutefois, si ce champs
est absent, le compilateur générera un numéro automatique.
Le champs serialVersionUID est utilisé lors de la désérialization
afin de s'assurer que les versions des classes Java soient concordantes.
Si ce n'est pas le cas, une InvalidClassException sera levée.
Or il se trouve que le calcul des serialVersionUID par défaut est
extrêmement sensible aux modifications apportées au code source et peut
même varier selon les compilateurs. Ce qui a pour inconvénient de provoquer
des InvalidClassExceptions inattendues lors de la désérialisation.
Il est ainsi fortement conseillé de gérer le serialVersionUID de toutes
classes sérializable, et bien sûr de modifier cette valeur lors d'un changement
sur les champs de la classe. Ce warning signalera ainsi toutes classes Serializable
sans définition du serialVersionUID explicite :
Main.java:5: warning: [serial] serializable class Main has no definition of serialVersionUID
Pour définir le serialVersionUID, il faut utiliser le code suivant (où 1L est le numéro de la version qui devra être changé à chaque modification sur les champs. La valeur n'a pas d'importance du moment qu'elle change lors d'un changement sur les champs à sérializer) :
private static final long serialVersionUID = 1L;
Il suffira ensuite de modifier ce numéro de version à chaque changement important dans la classe. Le plus simple étant d'incrémenter sa valeur.
Ce warning n'est actif qu'avec les options -Xlint ou -Xlint:serial de javac 5.0...
Ceci concerne également les classes qui héritent d'une classe qui implémente Serializable, puisqu'elle devient elle-même Serializable. Ainsi, ce warning concerne toutes les classes qui étendent les composants Swing par exemple...
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Lien : Que signifie le mot-clé transient ?
Lien : Qu'est-ce que la sérialisation ?
Ce warning permet d'afficher un message si les chemins passés à javac (classpath, sourcepath,...) sont inexistants. Il est ainsi très pratique pour vérifier que tous les éléments du CLASSPATH sont corrects. Ainsi, si un chemin est incorrect, il affichera le message suivant :
warning: [path] bad path element "../lib.jar": no such file or directory
Ce warning n'est actif qu'avec les options -Xlint ou -Xlint:path de javac 5.0...
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Ce warning signale des erreurs possibles dans les blocs switch si l'on n'utilise pas de break à la fin de chaque case. En effet, dans le code suivant :
switch (value) {
case 1:
System.out.println("Un");
case 2:
System.out.println("Deux");
case 3:
System.out.println("Trois");
}
Si value vaut 1, alors le code des trois case sera exécuté car il n'y a aucun break. Si cette conception est autorisée par le langage, elle est toutefois fortement déconseillée car elle complexifie l'utilisation du switch. Ainsi, le warning fallthrough, activé avec l'option -Xlint ou -Xlint:fallthrough de javac 5.0, permet de signaler l'oubli du mot-clef break à la fin d'un case, et donc le 'saut' possible au bloc case suivant :
Main.java:19: warning: [fallthrough] possible fall-through into case
case 2:
^
Main.java:21: warning: [fallthrough] possible fall-through into case
case 3:
^
Ce warning peut également être activé sur les versions précédentes de javac avec l'option -Xswitchcheck.
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Ce warning signale qu'une classe/méthode paramétrée avec les Generics est utilisée sans indication du type paramétré, ce qui lui fait perdre la sécurisation des opérations apporté par les Generics. Si ce warning est désactivé, une note sera quand même affichée à la fin de la compilation, par exemple :
Note: Main.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
Ce warning peut ainsi être affiché dans sa forme détaillée avec l'option -Xlint:unchecked de javac 5.0, ce qui donne par exemple :
Main.java:14: warning: [unchecked] unchecked call to add(E) as a member of the raw type java.util.List
list.add("string");
Dans cet exemple, on utilise la méthode add() de l'interface java.util.List sans avoir paramétré son type. Concrètement, ce warning apparaît avec le code suivant :
List list = new ArrayList();
list.add("string");
La raison est simple, l'interface java.util.List et la classe java.util.ArrayList qui l'implémente sont désormais paramétrées. Elles doivent donc être utilisées en utilisant les Generics :
List<String> list = new ArrayList<String>();
list.add("string");
L'utilisation de la liste est ainsi sécurisée car le compilateur vérifiera que seul des objets de type String y sont ajouté...
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Lien : [Java 5.0] Qu'est-ce que les Generics (types paramétrés) ?
Ce warning signale toutes les méthodes/classes dépréciées, c'est à dire qui ne devrait plus être utilisées. Si ce warning est désactivé, une note sera quand même affichée à la fin de la compilation, par exemple :
Note: Main.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Ce warning peut ainsi être affiché dans sa forme détaillée avec l'option -Xlint:deprecation de javac 5.0 (ou -deprecation avec une version plus ancienne du JDK). Il affichera ainsi l'élément concerné par la dépréciation :
Main.java:7: warning: [deprecation] getYear() in java.util.Date has been deprecated
return d.getYear();
Il faut ensuite consulter la documentation de la méthode/classe concernée afin de connaître la solution de remplacement.
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
En plus d'introduire de nouvelles fonctionnalités, Java 5.0 à introduit un grand nombre de nouveaux warnings afin d'indiquer un problème potentiel. Toutefois, il existe de nombreux cas où l'on ne peut pas faire autrement et ces warnings peuvent alors être assez dérangeant.
Il est heureusement possible d'utiliser l'annotation @SuppressWarning afin de supprimer un warning en particulier. Par exemple afin de supprimer le warning concernant l'absence de définition du serialVersionUID :
@SuppressWarnings("serial")
class MyFrame extends javax.swing.JFrame {
}
Ou encore afin d'utiliser une classe ou méthode dépréciée sans warning :
@SuppressWarnings("deprecation")
java.util.Date date = new java.util.Date(2007, 1, 1);
L'annotation attend en paramètre le(s) nom(s) des warnings à ignorer. Le JDK officiel de Sun utilise principalement les warnings suivants : deprecation, unchecked, fallthrough, path, serial et finally. Toutefois d'autre compilateur peuvent très bien utiliser d'autre type de warning. Si un nom de warning est inconnu pour le compilateur, il se doit de l'ignorer.
Attention : cacher un warning ne veut pas dire que le problème est résolu, et ne devrait être utiliser qu'en dernier recours s'il n'existe vraiment pas de solution alternative.
Il faut également faire attention à bien positionner l'annotation, qui agit sur l'élément dans sa totalité. Si elle est positionné devant une déclaration de variable cela ne concernera que cette ligne, mais devant une méthode ou une classe cela concernera la totalité de cette dernière, et cela risquerait de cacher d'autres warnings plus problématiques.
Il faut donc toujours essayer de limiter le plus possible la zone d'effet de l'annotation @SuppressWarning, par exemple en créant une méthode simplement destiné à recevoir le code en question.
Remarque : bien que comprise dans les spécifications de Java 5.0, cette annotation n'est effectivement supporté par le compilateur officiel du JDK de Sun qu'à partir de Java 5.0 update 6...
Lien : [Java 5.0] Comment activer/désactiver les warnings avec javac ?
Lien : Présentation de Java 5.0 (Tiger)


















