in

Gestion des exceptions en Java : les bases

Gestion des exceptions en Java : les bases

Le FileInputStream(String filename) le constructeur crée un flux d'entrée vers le fichier identifié par filename. Ce constructeur lance FileNotFoundException lorsque le fichier n'existe pas, fait référence à un répertoire ou qu'un autre problème connexe se produit. FileOutputStream(String filename) le constructeur crée un flux de sortie vers le fichier identifié par filename. Il jette FileNotFoundException lorsque le fichier existe mais fait référence à un répertoire, n'existe pas et ne peut pas être créé, ou qu'un autre problème connexe se produit.

FileInputStream fournit un int read() méthode permettant de lire un octet et de le renvoyer sous forme d'entier 32 bits. Cette méthode renvoie -1 à la fin du fichier. FileOutputStream fournit un void write(int b) méthode pour écrire l'octet dans les 8 bits inférieurs de b. L'une ou l'autre méthode génère IOException Quand quelque chose ne va pas.

La majeure partie de l'exemple est un while boucle qui se répète read()s l'octet suivant du flux d'entrée et write()s cet octet au flux de sortie, jusqu'à ce que read() signale la fin du fichier.

Le try La logique de copie de fichier du bloc est facile à suivre car cette logique n'est pas combinée avec un code de vérification des exceptions (if tests et connexes throw instructions cachées dans les constructeurs et les méthodes), code de gestion des exceptions (qui est exécuté dans un ou plusieurs catch blocs) et le code de nettoyage (pour fermer les fichiers source et de destination ; ce code est relégué à un finally En revanche, l'absence d'un framework orienté exception similaire dans C se traduit par un code plus verbeux, comme l'illustre l'extrait suivant d'un C plus grand cp application (dans l'archive de code de cet article) qui copie un fichier source vers un fichier de destination :

if ((fpsrc = fopen(argv(1), "rb")) == NULL)
{
   fprintf(stderr, "unable to open %s for readingn", argv(1));
   return;
}

if ((fpdst = fopen(argv(2), "wb")) == NULL)
{
   fprintf(stderr, "unable to open %s for writingn", argv(1));
   fclose(fpsrc);
   return;
}

while ((c = fgetc(fpsrc)) != EOF)
   if (fputc(c, fpdst) == EOF)
   {
      fprintf(stderr, "unable to write to %sn", argv(1));
      break;
   }

Dans cet exemple, la logique de copie de fichier est plus difficile à suivre car elle est mêlée à des codes de vérification des exceptions, de gestion des exceptions et de nettoyage :

  • Les deux == NULL et un == EOF les chèques sont l'équivalent du caché throw relevés et contrôles connexes.
  • Les trois fprintf() les appels de fonction sont le code de gestion des exceptions dont l'équivalent Java serait exécuté dans un ou plusieurs catch blocs.
  • Le fclose(fpsrc); l'appel de fonction est un code de nettoyage dont l'équivalent Java serait exécuté dans un finally bloc.
A Lire aussi  où acheter ce smartphone au meilleur prix ?

Utilisation de blocs catch pour intercepter les exceptions

La capacité de gestion des exceptions de Java est basée sur catch blocs. Cette section présente catch et divers catch blocs.

Le bloc catch

Java fournit le catch bloc pour délimiter une séquence d'instructions qui gèrent une exception. catch Le bloc a la syntaxe suivante :

catch (throwableType throwableObject)
{
   // one or more statements that handle an exception
}

Le catch Le bloc est similaire à un constructeur dans le sens où il possède une liste de paramètres. Cependant, cette liste ne contient qu'un seul paramètre, qui est un type jetable (Throwable ou l'une de ses sous-classes) suivi d'un identifiant pour un objet de ce type.

Lorsqu'une exception se produit, un objet jetable est créé et envoyé à la JVM, qui recherche l'exception la plus proche. catch bloc dont le type de paramètre correspond directement ou est le supertype de l'objet jetable lancé. Lorsqu'il trouve ce bloc, la JVM passe l'objet jetable au paramètre et exécute le catch instructions du bloc, qui peuvent interroger le throwable passé et gérer l'exception. Considérez l'exemple suivant :

catch (FileNotFoundException fnfe)
{
   System.err.println(fnfe.getMessage());
}

Cet exemple (qui étend le précédent try exemple de bloc) décrit un catch bloc qui attrape et gère les objets jetables de type FileNotFoundExceptionSeuls les objets jetables correspondant à ce type ou à un sous-type sont capturés par ce bloc.

Supposons que le FileInputStream(String filename) le constructeur lance FileNotFoundException. La JVM vérifie le catch bloquer suivant try pour voir si son type de paramètre correspond au type throwable. En détectant une correspondance, la JVM transmet la référence du throwable à fnfe et transfère l'exécution au bloc. Le bloc répond en invoquant getMessage() pour récupérer le message de l'exception, qu'il affiche ensuite.

Spécification de plusieurs blocs catch

Vous pouvez spécifier plusieurs catch bloque après un try bloc. Par exemple, considérez cet extrait plus long du document susmentionné Copy application:

FileInputStream fis = null;
FileOutputStream fos = null;
{
   fis = new FileInputStream(args(0));
   fos = new FileOutputStream(args(1));
   int c;
   while ((c = fis.read()) != -1)
      fos.write(c);
}
catch (FileNotFoundException fnfe)
{
   System.err.println(fnfe.getMessage());
}
catch (IOException ioe)
{
   System.err.println("I/O error: " + ioe.getMessage());
}

Le premier catch poignées de bloc FileNotFoundExceptions est lancé par l'un ou l'autre constructeur. Le deuxième catch poignées de bloc IOExceptions jeté du read() et write() méthodes.

A Lire aussi  Windows 11 22H2 commence à s'installer de force sur les PC, il va falloir faire la mise à jour

Lors de la spécification de plusieurs catch blocs, ne spécifiez pas de catch bloc avec un supertype avant un catch bloc avec un sous-type. Par exemple, ne placez pas catch (IOException ioe) avant catch (FileNotFoundException fnfe). Si vous le faites, le compilateur signalera une erreur car catch
(IOException ioe)
s'occuperait également FileNotFoundExceptionsable catch (FileNotFoundException
fnfe)
n'aurait jamais eu la chance d'être exécuté.

De même, ne spécifiez pas plusieurs catch blocs avec le même type jetable. Par exemple, ne spécifiez pas deux catch (IOException ioe) {} blocs. Sinon, le compilateur signale une erreur.

Utilisation des blocs finally pour nettoyer les exceptions

Qu'une exception soit gérée ou non, vous devrez peut-être effectuer des tâches de nettoyage, telles que la fermeture d'un fichier ouvert. Java fournit les finally bloquer à cet effet.

Le finally le bloc est composé de mots-clés finally suivi d'une séquence d'instructions à exécuter délimitée par des accolades. Il peut apparaître après la dernière catch bloquer ou après le try bloc.

Nettoyage dans un contexte d'essai-attrape-finalement

Lorsque des ressources doivent être nettoyées et qu'aucune exception n'est levée par une méthode, une finally le bloc est placé après la finale catch bloc. Ceci est démontré par ce qui suit Copy extrait:

FileInputStream fis = null;
FileOutputStream fos = null;
try
{
   fis = new FileInputStream(args(0));
   fos = new FileOutputStream(args(1));
   int c;
   while ((c = fis.read()) != -1)
      fos.write(c);
}
catch (FileNotFoundException fnfe)
{
   System.err.println(fnfe.getMessage());
}
catch (IOException ioe)
{
   System.err.println("I/O error: " + ioe.getMessage());
}
finally
{
   if (fis != null)
      try
      {
         fis.close();
      }
      catch (IOException ioe)
      {
         // ignore exception
      }

   if (fos != null)
      try
      {
         fos.close();
      }
      catch (IOException ioe)
      {
         // ignore exception
      }
}

Si le try le bloc s'exécute sans exception, l'exécution passe à la finally bloc pour fermer les flux d'entrée/sortie du fichier. Si une exception est levée, le finally le bloc s'exécute après le approprié catch bloc.

A Lire aussi  une occasion à ne pas rater !

FileInputStream et FileOutputStream hériter d'un void close() méthode qui lance IOException lorsque le flux ne peut pas être fermé. Pour cette raison, j'ai enveloppé chacun des fis.close(); et fos.close(); dans un try bloquer. J'ai laissé le associé catch bloc vide pour illustrer l’erreur courante consistant à ignorer une exception.

Un vide catch Le bloc invoqué avec le throwable approprié n'a aucun moyen de signaler l'exception. Vous risquez de perdre beaucoup de temps à rechercher la cause de l'exception, pour découvrir ensuite que vous auriez pu la détecter plus tôt si le catch Le bloc avait signalé l'exception, même si ce n'était que dans un journal.

Faire le ménage dans un contexte d'essai final

Lorsque des ressources doivent être nettoyées et qu'une exception est levée par une méthode, un finally le bloc est placé après le try bloc : il n'y a pas catch blocs. Considérez l'extrait suivant d'une deuxième version du Copy application:

public static void main(String() args)
{
   if (args.length != 2)
   {
      System.err.println("usage: java Copy srcfile dstfile");
      return;
   }

   try
   {
      copy(args(0), args(1));
   }
   catch (IOException ioe)
   {
      System.err.println("I/O error: " + ioe.getMessage());
   }
}

static void copy(String srcFile, String dstFile) throws IOException
{
   FileInputStream fis = null;
   FileOutputStream fos = null;
   try
   {
      fis = new FileInputStream(srcFile);
      fos = new FileOutputStream(dstFile);
      int c;
      while ((c = fis.read()) != -1)
         fos.write(c);
   }
   finally
   {
      if (fis != null)
         try
         {
            fis.close();
         }
         catch (IOException ioe)
         {
            System.err.println(ioe.getMessage());
         }

      if (fos != null)
         try
         {
            fos.close();
         }
         catch (IOException ioe)
         {
            System.err.println(ioe.getMessage());
         }
   }
}

La logique de copie de fichiers a été déplacée dans un copy() méthode. Cette méthode est conçue pour signaler une exception à l'appelant, mais elle ferme d'abord chaque fichier ouvert.

Cette méthode throws clause ne répertorie que IOExceptionIl n'est pas nécessaire d'inclure FileNotFoundException parce que FileNotFoundException sous-classes IOException.

Encore une fois, le finally La clause présente beaucoup de code juste pour fermer deux fichiers. Dans la deuxième partie de cette série, vous découvrirez la clause try-with-resources déclaration, ce qui évite d'avoir à fermer explicitement ces fichiers.

En conclusion

Cet article vous a présenté les bases du framework orienté exception traditionnel de Java, mais il reste encore beaucoup à comprendre. La seconde moitié de ce didacticiel présente les fonctionnalités de langage orienté exception et les types de bibliothèques les plus avancés de Java, notamment try-with-resources.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

GIPHY App Key not set. Please check settings

Naomi Eto : « L’arbitrage n’a pas été de notre côté, on ne sait pas pourquoi »

Naomi Eto : « L’arbitrage n’a pas été de notre côté, on ne sait pas pourquoi »

La Chine promouvra l’ouverture institutionnelle du commerce des services