gestion des exception

Status:
Tags: <% tp.file.cursor(3) %>
Links: <% tp.file.cursor(4) %>


Gestion des exception

<% tp.file.cursor(5) %>


Pasted image 20240311102303.png

introduction

Souvent, un programme doit traiter des situations inattendues (exceptionnelles) en dehors de sa tache principale.

Une situation exceptionnelle peut être assimilée à une erreur qui génère une interruption gérée habituellement par le système d’exploitation.

Exemples d’erreurs/exceptions courantes :
Accès non autorisé à une zone mémoire (erreur de manipulation de pointeur), division par zéro, débordement d'indices dans une collection, etc

Exemple 1

public class TestSansException {
	public static void main(java.lang.String[] args) {
		int i = 3;
		int j = 0;
		System.out.println("Avant exception");
		System.out.println("résultat = " + (i / j));
		System.out.println("ne sera jamais exécutée !");
}
}

Lors de l’exécution, la JVM va générer cette erreur (exception) java.lang.ArithmeticException: / by zero Et le programme TestSansException sera interrompu.

Definition

Une exception est un événement, se produisant lors de l’exécution d’un programme, qui interrompt l’enchaînement normal des instructions.

L’objectif est de gérer ces exceptions par le programme lui-même en les interceptant (en les capturant ).

Le principe consiste à repérer les morceaux de code (par exemple, une division ) qui pourraient générer une exception, de capturer l'exception correspondante et enfin de la traiter, c'est-à-dire d'afficher un message personnalisé et de continuer l'exécution.

Les exceptions représentent un mécanisme de gestion des erreurs Il se compose de (en java) :

Ce mécanisme permet de renforcer la fiabilité des programmes

Gestion des exceptions en java

En Java, on distingue trois types d'erreurs :

Les erreurs grave

  1. Les erreurs graves qui causent généralement l'arrêt du programme et qui sont représentées par la classe java.lang.Error .

Exemple : OutOfMemoryError

Les erreurs qui doivent généralement être traitées

  1. Les erreurs qui doivent généralement être traitées et qui sont représentées par la classe java.lang.Exception.

Exemple : FileNotFoundException

Les erreurs qui peuvent ne pas être traitées

  1. Les erreurs qui peuvent ne pas être traitées et qui sont des objets de la classe java.lang.RuntimeException qui hérite de java.lang.Exception.

Exemple : ArrayIndexOutOfBoundsExceptions

Pasted image 20240311104810.png

Instruction try/catch/finally
Le bloc «try» rassemble les blocs d’instructions susceptibles de produire des erreurs ou des exceptions.

try {
	bloc_susceptible_de_produire_des_erreurs
} catch (type_exception_1 arg_1) {
	bloc_1
} catch (type_exception_2 arg_2) {
	bloc_2
}...
} finally {
	bloc_optionnel_qui_s_exécute_toujours
}

Finally

Exemple : Instruction try/catch/finally

public class TestException {
	public static void main(java.lang.String[] args) {
		int i = 3; int j = 0;
		try {
			System.out.println("résultat = " + (i / j));
		} catch (ArithmeticException e) {
			System.out.println(" Attention ! Division par 0");
		}
		System.out.println("s’exécute sans problème");
	}
}

Instruction try/catch/finally

public class TestException {
	public static void main(java.lang.String[] args) {
		int i = 3; int j = 0;
		try {
			System.out.println("résultat = " + (i / j));
		} catch (ArithmeticException e) {
			System.out.println("getmessage : " + e.getMessage());
			System.out.println("toString : " + e.toString());
			System.out.println("printStackTrace : " );
			e.printStackTrace());
		}
		System.out.println("s'excute sans problème");
	}
}

Méthodes de l’objet Exception

getmessage() affiche le message de l’exception levée (e.g. / by zero).
toString() affiche en plus le nom complet de cette classe exception (e.g. java.lang.ArithmeticException: / by zero).
printStackTrace() : affiche l'état de la pile lors de la remontée de l'exception. Utile pour trouver les causes de celle-ci.

java.lang.ArithmeticException: / by zero
	at TestException.main(TestException.java:7)
	at __SHELL39.run(__SHELL39.java:6)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at
	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessor
	Impl.java:62)
	at
	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethod AccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:483)
	at bluej.runtime.ExecServer$3.run(ExecServer.java:730)

Exemple de propagation de l’exception

class Propagation {  
	public static void m1() { m2(); }  
	public static void m2() { m3(); }  
	public static void m3() {throw new RuntimeException();}  
	public static void main(String[] args) {  
		m1();  
	} // end of main()  
} 
java.lang.RuntimeException
at Propagation.m3(Propagation.java:4)  
at Propagation.m2(Propagation.java:3)  
at Propagation.m1(Propagation.java:2)  
at Propagation.main(Propagation.java:6)  
UABB-Tlemcen – Département d’Informatique - cours de POO 2 pour Ing. 2

Quelques exceptions prédéfinies

Il existe en java des exceptions prédéfinies :

Exemple d’exceptions prédéfinies

class Exemple3{  
	static int[] tableau = {17, 12, 15, 38, 29, 157, 89, -22, 0, 5};  
	static int division(int indice, int diviseur){  
	return tableau[indice]/diviseur;  
}  
public static void main(String[] args){  
	int x, y;  
	boolean ok = true;  
	Integer i;  
	java.util.Scanner scan = new java.util.Scanner(System.in);  
	do{  
		System.out.print("Entrez l’indice de l’entier a diviser: ");  
		x = scan.nextInt();  
		System.out.print("Entrez le diviseur: ");  
		y = scan.nextInt();  
		System.out.println("Le resultat de la division est: ");  
		System.out.println(division(x,y));  
		i=null;  
		if (y==1) {i=y;ok=true;}  
		System.out.print("Objet initialisé : "+i.toString());  
	}while(!ok);  
	}  
}  

Aussi

Exemple

class Point {  
	public static final int X_MAX = 1024, Y_MAX = 768;  
		private int x, y;  
		public Point (int a, int b) {  
			x = a;  
			y = b;  
		}  
		}  

Créer son propre type d'exception

en héritant de la classe Exception

class CoordonneesIllegalesException extends Exception {  
	public CoordonneesIllegalesException () {  
		super("Coordonnées illégales."); }  
	public CoordonneesIllegalesException (String msg) {  
		super(msg); }  
	}
}

Lancer une exception

Une exception peut être lancée via la syntaxe suivante :
throw exception;
où exception est une expression dont la valeur doit être un objet de type Throwable.

class Point { 
	public static final int X_MAX = 1024, Y_MAX = 768;
	private int x, y;
	public Point (int a, int b) throws CoordonneesIllegalesException{
		if (a < 0 || a > X_MAX || b < 0 || b >= Y_MAX) {
		throw new CoordonneesIllegalesException("Coordonnées illégales.");
	}
	x = a;
	y = b;
	}
}

public class TestException3 {
	public static void main(java.lang.String[] args) {
		try {
			Point p = new Point (-1, 5);
		} catch(CoordonneesIllegalesException e) {
			System.out.println(e.getMessage());
		}
	}
}

Remarque

Si un événement indésirable survient dans le bloc try, la partie éventuellement non exécutée de ce bloc est abandonnée et le premier bloc catch est traité.

Exemple:

try {
System.out.print("Entrez l’indice de l’entier a diviser: ");
x = scan.nextInt();
System.out.print("Entrez le diviseur: ");
y = scan.nextInt();

Dans cet exemple, les instructions qui suivent dans le bloc try:

System.out.print("Entrez le diviseur: ");
y = scan.nextInt();

Son utilité réside dans le fait qu'elle transmet la responsabilité de la gestion de cette exception à l'appelant de la méthode, plutôt que de la traiter localement dans la méthode elle-même.

Checked exceptions, also known as compile-time exceptions, are exceptions that must be either caught or declared in the method signature using the throws keyword.

These exceptions are typically used to handle expected error scenarios that a program can recover from..

Utilisation de throws :

Transparence des exceptions : déclare et informe explicitement les développeurs qui utilisent la méthode qu'elle peut lancer une exception particulière.
Définition de la responsabilité la responsabilité de la gestion de ces exceptions incombe à l'appelant.
Propagation des exceptions : propager les exceptions vers des niveaux supérieurs dans la pile d'appels..

La classe Throwable

La classe de base pour le traitement des erreurs.

Dans le constructeur Throwable(String) :
La chaîne en paramètre permet de définir un message qui décrit l'exception
==String getMessage( ) ==: retourne le message
==void printStackTrace( ) ==: affiche l'exception et l'état de la pile d'exécution au moment de son appel.

Multiples exceptions dans une clause catch

Il n'est pas rare d'avoir à dupliquer les mêmes lignes de code dans le bloc de code de plusieurs clauses catch().

try {  
	// traitements pouvant lever les exceptions  
} catch(ExceptionType1 e1) {  
	// Traitement de l'exception  
} catch(ExceptionType2 e2) {  
	// Traitement de l'exception  
} catch(ExceptionType3 e3) {  
	// Traitement de l'exception  
} 

A partir de Java 7, la même portion de code est simplifiée : il suffit de déclarer les exceptions dans une même clause catch en les séparant par le caractère "|".

try {  
	// traitements pouvant lever les exceptions  
} catch(ExceptionType1|ExceptionType2|ExceptionType3 ex) {  
	// Traitement de l'exception  
}

Si plusieurs types d'exceptions sont déclarés dans une clause catch alors la variable qui permettra un accès à l'exception concernée est implicitement déclarée final.

try et la gestion des ressources

L'instruction try-with-resources (Avant Java 7)

Des ressources comme des fichiers, des flux, des connexions, ...
doivent être fermées explicitement par le développeur pour libérer les ressources sous-jacentes qu'elles utilisent.

Généralement cela est fait en utilisant un bloc try / finally pour garantir leur fermeture dans la quasi-totalité des cas.

Fermer explicitement la ressource implique un risque potentiel d'oubli de fermeture qui entraine généralement une fuite de ressources.

Exemple de fuite de ressources :

Avec Java 7, le mot clé try peut être utilisé pour déclarer une ou plusieurs ressources.
Une nouvelle interface a été définie pour indiquer qu'une ressource peut être fermée automatiquement :

java.lang.AutoCloseable

Tous les objets qui implémentent l'interface AutoCloseable peuvent être utilisés dans une instruction de type try-with-resources. Cette dernière garantit que chaque ressource déclarée sera fermée à la fin de l'exécution de son bloc de traitement.

L'interface java.lang.Autocloseable possède une unique méthode close() qui sera invoquée pour fermer automatiquement la ressource encapsulée par l'implémentation de l'interface.

L'interface java.io.Closable introduite par Java 5 hérite de l'interface AutoCloseable : ainsi toutes les classes qui implémentent l'interface Closable peuvent être utilisées comme ressource dans une instruction try-with-resource.

Exemple de L'instruction try-with-resources

try (BufferedReader bufferedReader = new BufferedReader(new FileReader("monfichier.txt"))) {
	String ligne=null;
while ((ligne = bufferedReader.readLine()) != null) {
	System.out.println(ligne);
}
} catch (IOException ioe) {
	ioe.printStackTrace();
}

L'instruction try-with-resource présente un petit inconvénient : il est obligatoire de définir la variable qui encapsule la ressource entre les parenthèses qui suivent l'instruction try. Il n'est par exemple pas possible de fournir en paramètre de
l'instruction try une instance déjà créé.

public static void afficherFichier(Reader flux) throws IOException {
	try (Reader closeableReader = flux) {
		int donnee;
	while ((donnee = flux.read()) >= 0) {
		System.out.print((char) donnee);
	}
}

Dans l'exemple ci-dessus, comme la variable définie et celle existante pointent sur la même référence, les deux variables.
peuvent être utilisées indifféremment. L'instruction try-with-resource se charge de fermer automatiquement le flux.

Voir Exemple de la classe TestCloseRessource

Une exception chaînée est une fonctionnalité qui permet à une exception d'être associée à une autre exception en tant que sa cause.

Exemple de la classe ExceptionChainee

class ExceptionA extends Exception {
	public ExceptionA(String message, Throwable cause) {
		super(message, cause);
	}
}
class ExceptionB extends Exception {
	public ExceptionB(String message) {
		super(message);
	}
}
public static void methodeB() throws ExceptionB {
	// Simuler une exception
	throw new ExceptionB("Exception B s'est produite.");
	}
} //fin du main

public static void methodeA() throws ExceptionA {
	try {
		// Appeler une autre méthode qui peut lever une exception
		methodeB();
	} catch (ExceptionB e) {
		// Lancer une nouvelle exception en chaînant l'exception
		// précédente
		throw new ExceptionA("Exception A s'est produite.", e);
	}
}
public class ExceptionChainee {
	public static void main(String[] args) {
		try {
			// Appeler une méthode qui peut lever une exception
			methodeA();
		} catch (ExceptionA e) {
			// Attraper l'exception et afficher la cause, si elle existe
			Throwable cause = e.getCause();
		if (cause != null) {
			System.out.println("Cause de l'exception : " + cause.getMessage());
		} else { System.out.println("Aucune cause trouvée."); }
	}
}

Explication

La methodeA() appelle methodeB(), qui peut lever une ExceptionB.

Lorsque ExceptionB est attrapée dans methodeA(), une nouvelle ExceptionA est lancée en chaînant l'exception précédente (ExceptionB) en tant que cause.

Dans le bloc catch dans main(), nous utilisons getCause() pour obtenir la cause de ExceptionA et afficher son message.

Application Gestion des exception

type 1

type 1

type 1

Criticisms Gestion des exception

type 1

type 1

type 1

Future Of Gestion des exception

type 1

type 1

type 1

References:

Created:: 2024-03-11 10:21