Erreur/Exception

Objectifs

  • Comprendre ce qu'est une erreur/exception en Java

  • Différencier les erreurs de logique métier, de compilation et d'exécution

  • Les approches de résolution des erreurs de logique métier et de compilation

Mise en situation

Lorsque nous lançons un programme, on peut rencontrer des problèmes, sous la forme de différents types d'erreurs et faire face à un comportement imprévisible ou un fonctionnement exceptionnel de notre programme.

Il existe deux types de familles d'erreurs qui se produisent souvent :

  • Les erreurs de code logiciel, ce qui inclut les erreurs de compilation et les erreurs d'exécution

  • Les erreurs de logique métier .

Erreur de code logiciel

Ce sont des erreurs liées au code et au fonctionnement de la JVM. Lorsqu'elles se produisent, la JVM arrête le programme et produit un message d'erreur. Java va donc lever une exception (relever une erreur) car nous sommes confrontés à un comportement exceptionnel de l'application (le plantage ou crash de l'application).

On distingue deux types d'erreurs:

  1. Les erreurs de compilation : elles surviennent lors de la phase de compilation du code, c'est-à-dire la phase où la JVM va traduire (compiler) le fichier texte du code source .java en fichier binaire .class (bytecode/code machine ou fichier exécutable par la machine) grâce au compilateur javac.

  2. Les erreurs d'exécution : elles surviennent lors de la phase d'exécution du fichier binaire .class par la JVM (Java Virtual Machine).

1. Les erreurs de compilation/Throwable, Error

Ces erreurs portent généralement sur les violations des règles syntaxiques et sémantiques de la grammaire du langage Java.

ExempleRègles Syntaxiques

Une violation des règles grammaticales du langage peut être par exemple : le non-respect des règles de nomination de variables...

1
public class Main {
2
	public static void main(String[] args) {	System.out.println "hello World	}
3
}
1
console@user:~$
2
java: '(' expected
3
java: ')' expected
4
java: unclosed string literal
5
java: ';' expected

Ce code viole quelques règles syntaxiques qui sont exposées dans la console telles que :

  • les parenthèses ouvrantes et fermantes manquantes à l'appel de la méthode println( ) pour l'affichage des données à la console

  • la non-fermeture de la chaîne de caractère par un

  • et enfin le point-virgule manquant ; à la fin de l'instruction.

ExempleRègles sémantiques

Une violation des règles sémantiques peut être par exemple : l'utilisation de mots interdits, de code non interprétable, de types incorrects...

1
public class Main {
2
	public static void main(String[] args) {
3
		...
4
		String 123 = "123";
5
6
		boolean zero = 0;
7
8
		int entier = 2.5;
9
10
		float nombre-a-virgule = 100;
11
		System.out.println(~);
12
	}
13
}
1
java: not a statement
2
java: incompatible types: int cannot be converted to boolean
3
java: possible lossy conversion from double to int
4
java: illegal start of expression

Ce code viole plusieurs règles sémantiques du langage Java telles que :

  • les noms de variables Java ne peuvent pas commencer par des nombres ou n'être simplement que des nombres

  • des conversions de types incorrects ou l'insertion de types incompatibles entre eux

  • des éléments qui ne sont pas gérés par le langage Java.

FondamentalCorrection des erreurs de compilation

Choisissez de bons éditeurs de code comme Atom, VS Code, Sublime Text... ou encore mieux, de bons IDE comme Eclipse, NetBeans ou Intellij Idea Ultimate qui peuvent détecter les erreurs de grammaire (syntaxe/sémantique) en mettant en évidence (coloration, surlignage...) des parties de code contenant des anomalies directement lors de l'écriture de votre code.

Cependant, ils ne sont pas toujours suffisants ou ne répondent pas toujours à toutes nos envies. Par conséquent, Java fournit un mécanisme de gestion des erreurs : la gestion des exceptions qu'on verra au chapitre suivant.

2. Les erreurs d'exécution/RuntimeError

Lorsque l'étape de compilation est terminée et que le programme produit un bytecode, on passe à la phase d'exécution de ce bytecode.

Pendant la phase d'exécution, le programme peut se terminer brusquement et donc détecter des erreurs d'exécution impossibles à détecter lors de la phase de compilation.

ExempleType d'erreur d'exécution

Ce genre d'erreur se produit lorsque le programme effectue une opération interdite ou illégale.

1
public class DiviserParZero {
2
    public static void main(String[] args) {
3
        int distance = 10;
4
        int temps = 0;
5
        System.out.println("La vitesse vaut ==> " + distance / temps);
6
    }
7
}
1
Exception in thread "main" java.lang.ArithmeticException: / by zero
2
	at DiviserParZero.main(DiviserParZero.java)

La JVM vient de relever une ArithmeticException qui expose l'exécution d'une opération illégale ou interdite  : la division par zéro.

Nous savons bien que la vitesse est le rapport de la distance par le temps. La compilation de ce programme se passe sans problème.

Cependant, l'opération de division par zéro est illégale, donc cette erreur sera détectée à l'exécution de ce programme.

FondamentalCorrection des erreurs d'exécution

En testant notre code, et en utilisant des techniques de vérifications formelles (ex PathFinder), on arrive à bien s'assurer de ne pas rencontrer d'erreurs d'exécution.

On peut utiliser le système de débogage ou la gestion des exceptions pour traiter ce genre d'erreurs.

Erreur de logique métier

Ce sont des erreurs difficiles à détecter car elles ne provoquent pas d'interruption de programme mais produisent plutôt des résultats logiquement incohérents.

ExempleType d'erreur de logique métier classique

1
public class Main {
2
	public static void main(String[] args) {
3
  	String[] nba = { "Lebron James", "Stephen Curry", "Kevin Durant"};
4
  	String[] uefa = { "Cristiano Ronaldo", "Lionel Messi", "Kylian Mbappé"};
5
6
		/* Souhait : Afficher la liste des joueurs de la NBA */
7
		for (String nba_players : uefa) {
8
			System.out.println(nba_players);
9
		}
10
	}
11
}
1
console@user:~$
2
Cristiano Ronaldo
3
Lionel Messi
4
Kylian Mbappé

En effet, l'erreur illustrée ci-dessus sera difficile à détecter car l'application affiche bien ce qu'on lui demande et ne plante pas.

Cependant, Lionel Messi sur la liste des basketteurs NBA est logiquement incorrect (voire impossible).

FondamentalCorrection des erreurs de logique métier

Pour détecter et corriger les erreurs de logique métier, on a besoin des programmes appelés debugger qui vont suivre, instruction par instruction, l'exécution du programme et relever le contenu de toutes les variables à chaque étape.

SyntaxeÀ retenir

Dans ce chapitre, les points importants à retenir sont :

  • Les erreurs de logique métier sont difficiles à détecter car elles passent souvent inaperçues puisque le programme compile et s'exécute sans signaler un quelconque problème ; on a vu comment les détecter et les corriger.

  • Les erreurs de code Java qui se produisent :

    • lors de la phase de compilation du programme : on a abordé différentes approches, techniques et mécanismes qu'offrent certains outils pour les détecter et les corriger tels que les bons éditeurs de code et les bons EDI, un débugger ou la gestion des exceptions.

    • lors de la phase d'exécution du programme : on a abordé différentes approches qu'offrent certains outils pour les détecter et les corriger tels que PathFinder et aussi le mécanisme Java pour la gestion des exceptions.

Complément

Les règles de grammaire (spécifications) Java à respecter afin d'éviter les erreurs de compilation : https://docs.oracle.com/javase/specs/jls/se15/html/jls-2.html

Lien vers la documentation de PathFinder : http://javapathfinder.sourceforge.net/