1. Dérogations

>

Enfin, les programmeurs ont pensé à normaliser et à automatiser la gestion des erreurs. Cela s'est produit lorsque les exceptions ont été inventées. Désormais, le mécanisme d'exception gère 80 % des situations exceptionnelles.

Si un chercheur proposait des exceptions, c'était probablement le sujet de sa thèse de doctorat. Si un programmeur l'a inventé, il a peut-être reçu une tape amicale dans le dos d'un collègue : "Ça va, mon frère."

Lorsqu'une erreur se produit dans un programme Java, telle qu'une division par 0, des choses merveilleuses se produisent :

La première étape

Un objet d'exception spécial est créé, qui contient des informations sur l'erreur qui s'est produite.

Tout en Java est un objet, et les exceptions ne sont pas des exceptions 🙂 Les objets d'exception ont leurs propres classes, et la seule chose qui les distingue des classes ordinaires est qu'ils héritent de la classe Throwable.

Deuxième étape

L'objet d'exception est "levé". Peut-être que la formulation ici pourrait être meilleure. "Lancer une exception" revient plus à déclencher une alarme incendie ou à déclencher une alerte "DEFCON 1".

Lorsqu'une exception est lancée sur la machine Java, le fonctionnement normal du programme s'arrête et les "protocoles d'urgence" commencent.

Troisième étape

La méthode dans laquelle l'exception a été levée se termine immédiatement. L'exception est transmise à la méthode appelante, qui se termine également immédiatement. Et ainsi de suite dans la chaîne jusqu'à mainla sortie de la méthode. Lorsque la mainméthode se termine, le programme aussi.

Exemple:

Code Sortie console
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Your attention, please! Preparing for the end of the world");
      endTheWorld();
      System.out.println("The world ended successfully");
   }

   public static void endTheWorld()
   {
      System.out.println("We're doing something important");
      doSomeWork(0);
      System.out.println("Everything is working well");
   }

   public static void doSomeWork(int n)
   {
      System.out.println("Nothing terrible will happen: " + n);
      System.out.println(2 / n);
      System.out.println("Nothing terrible happened: " + n);
   }
}
Your attention, please! Preparing for the end of the world
We're doing something important
Nothing terrible will happen: 0

Une exception se produit à la ligne 20 : division par 0. La machine Java crée immédiatement une exception — un ArithmeticExceptionobjet et le « lance » à la méthode.

La divide()méthode se termine immédiatement, donc nous ne voyons jamais la chaîne : Rien de grave ne s'est produit : 0. Le programme retourne à la endTheWorld()méthode, et la situation se répète : il y a une exception non gérée dans le système, ce qui signifie que la endTheWorld()méthode se termine également de manière anormale. Ensuite, la mainméthode se termine et le programme s'arrête.

A quoi servent ces exceptions ? Eh bien, vous pouvez écrire votre propre code pour intercepter des types particuliers d'exceptions et écrire votre propre logique pour gérer des situations exceptionnelles.


2. Attraper les exceptions :try-catch

Java dispose d'un mécanisme de capture d'exception qui vous permet d'arrêter cet arrêt anormal des méthodes. Il ressemble à ceci :

try
{
   // Code where an exception might occur
}
catch(ExceptionType name)
{
   // Exception handling code
}

Cette construction s'appelle un try-catchbloc.

Le code où des exceptions peuvent se produire est entouré d'accolades, précédé du mot try.

Après les accolades, nous avons le catchmot clé et, entre parenthèses, la déclaration d'une variable d'exception . Elle est suivie d' accolades qui enveloppent le code à exécuter si une exception du type spécifié se produit .

Si aucune exception n'est levée lors de l'exécution du " code primaire ", alors le code à l'intérieur du bloc catch ne sera pas exécuté. Si une exception se produit, elle le sera (si le type de l'exception levée est le même que le type de la variable entre parenthèses).

Exemple:

Code Sortie console
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Hadron Collider launched");

      try
      {
         launchHadronCollider(1);
         launchHadronCollider(0);
      }
      catch(Exception e)
      {
         System.out.println("Error! Caught an exception");
         System.out.println("The planet was sucked into a black hole!");
      }

      System.out.println("The Hadron Collider stopped");
   }

   public static void launchHadronCollider(int n)
   {
      System.out.println("Everything is working well: " + n);
      System.out.println(2/n);
      System.out.println("There are no problems: " + n);
   }
}
Hadron Collider launched
Everything is working fine: 1
2
There are no problems: 1
Everything is working fine: 0
Error! Caught an exception
The planet has been sucked into a black hole!
The Hadron Collider is stopped


3. catchBlocs multiples

Plusieurs blocs catch

En théorie, toutes sortes d'exceptions peuvent être lancées dans un bloc de code. Certains que vous voudrez gérer d'une manière, d'autres d'une autre manière, et d'autres encore, vous déciderez de ne pas les gérer du tout.

Les développeurs Java ont décidé de vous aider et de vous laisser écrire non pas un mais plusieurs catchblocs après le trybloc.

try
{
   // Code where an exception might occur
}
catch (ExceptionType1 name1)
{
   // Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
   // Code for handling ExceptionType2
}
   catch (ExceptionType3 name3)
{
   // Code for handling ExceptionType3
}

Exemple:

Code Sortie console
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch (ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method


4. Ordre des catchblocs

Les exceptions qui se produisent dans un trybloc ne peuvent être interceptées que par un seul catchbloc. Vous ne pouvez pas avoir une situation de gestion des exceptions où le code de plusieurs catchblocs est exécuté.

Mais l'ordre des blocs est important.

Vous pouvez avoir une situation où une exception peut être interceptée par plusieurs blocs. Si tel est le cas, l'exception sera interceptée par le bloc catch qui vient en premier (le plus proche du trybloc).

Comment pouvez-vous avoir une situation où plusieurs blocs catch peuvent intercepter la même exception ?

Toutes les exceptions appartiennent à une seule hiérarchie d'héritage — voir le diagramme.

Hiérarchie des exceptions

Un ArithmeticExceptionobjet peut être affecté à une variable dont le type est ArithmeticExceptionou à l'une de ses classes ancêtre : RuntimeException , Exceptionet Throwable— voir le diagramme.

Nous parlerons davantage des classes d'héritage et d'ancêtre au niveau 21.

Ce code compilera très bien:

Avantages de l'héritage :
ArithmeticException ae    = new ArithmeticException();
RuntimeException runtime  = new ArithmeticException();
Exception exception       = new ArithmeticException();
Throwable trwbl           = new ArithmeticException();

Vous pouvez donc attraper un ArithmeticExceptionavec l'un des 4 catchblocs ci-dessus.

Exemple 1:

Code Sortie console
class Solution
{
   public static void main(String[] args)
   {
      System.out.println("Start of main method");
      try
      {
         calculate(0);
      }
      catch(ArithmeticException e)
      {
         System.out.println("Division by 0");
      }
      catch(Exception e)
      {
         System.out.println("Caught some kind of exception");
      }

      System.out.println("End of main method");
   }

   public static void calculate(int n)
   {
      System.out.println("Start of calculate method: " + n);
      System.out.println(2/n);
      System.out.println("End of calculate method: " + n);
   }
}
Start of main method
Start of calculate method: 0
Division by 0
End of main method

Dans cet exemple, le ArithmeticExceptionpeut être capturé à la fois par les blocs catch (Exception e)et catch (ArithmeticException e). Il sera attrapé par le bloc le plus proche du trybloc - le premier catchbloc.

Pour éviter les surprises, il est préférable de placer catchdes blocs qui peuvent intercepter presque toutes les exceptions vers la fin de la liste des catchblocs.

Le Throwabletype est généralement capable d' attraper toutes les exceptions possibles en Java . Si vous le mettez dans le premier catchbloc, le code ne se compilera pas, car le compilateur sait qu'il existe des blocs de code inaccessibles.