Exception (niveau 2)

le cours de niveau 1 sur les exceptions

générer ses exceptions

Source de Equation6.java
public class Equation6 {
  private int a, b;
  public Equation6(int a, int b) {
    this.a=a; this.b=b;
  }
  public void afficher() { 
    System.out.println(a+" * X = "+b);
  } 
  int solution() throws EquationException {
    if (a == 0)
      throw new EquationException("pas de solution !");
    return b/a;
  }
}
Source de EquationException.java
public class EquationException 
       extends ArithmeticException {
  public EquationException() {
    super();
  }
  public EquationException(String s) {
    super(s);
  }
}
Source de Prog107.java
public class Prog107 {
  public static void main(String args[]) {
    int valeurA = Integer.valueOf(args[0]).intValue();
    int valeurB = Integer.valueOf(args[1]).intValue();
    Equation6 equa = new Equation6(valeurA,valeurB);
    equa.afficher();
    try {
      int x = equa.solution();
      System.out.println("resultat : X = "+x);
    } catch (EquationException e) {
      System.out.println("erreur : "+e);
    } 
  }
}
EXECUTION
$ java Prog107 2 4
2 * X = 4
resultat : X = 2
$ java Prog107 0 4
0 * X = 4
erreur : EquationException: pas de solution !
  • les lignes de la classe :
    • la classe équation génère une exception particulière au lieu de ArithmeticException
    • Néanmoins, cette exception hérite de ArithmeticException

Héritage des exceptions

exemple avec finally A FAIRE

Source de prog.java
exemple client serveur 
client telnet -e $ localhost 3333
serveur echo resistant au close
EXECUTION
exe
  • les lignes de la classe :
    • blabla

Fonctionnement des try-catch-finally

Source de Except1.java
import java.io.*;
public class Except1 {
  public static void main(String args[]) {
    System.out.println("main : debut");
    Except1 ex = new Except1();
    try {
      System.out.println("main : appel de methodeA");
      ex.methodeA(args);
      System.out.println("main : retour de methodeA");
    } catch (Exception e) {
      System.out.println("main : catch une Exception : "+e);
    }
    System.out.println("main : fin");
  }
  public void methodeA(String args[]) {
    System.out.println("  methodeA : debut");
    try {
      System.out.println("  methodeA : appel de methodeB");
      this.methodeB(args);
      System.out.println("  methodeA : retour de methodeB");
      if (args.length > 99)
        throw new IOException();
    } catch (IOException e) {
      System.out.println("  methodeA : catch une Exception : "+ e);
    } finally {
      System.out.println("  methodeA : execute finally");
    }
    System.out.println("  methodeA : fin");
  }
  public void methodeB(String args[]) {
    System.out.println("    methodeB : debut");
    try {
      System.out.println("    methodeB : tente d'acceder a args[99]");
      String s = args[99];
      System.out.println("    methodeB : a reussi a acceder a args[99]");
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("    methodeB : catch une Exception : "+ e);
    } finally {
      System.out.println("    methodeB : execute finally");
    }
    System.out.println("    methodeB : fin");
  }
}
EXECUTION
$ java Except1
main : debut
main : appel de methodeA
  methodeA : debut
  methodeA : appel de methodeB
    methodeB : debut
    methodeB : tente d'acceder a args[99]
    methodeB : catch une Exception : 
      java.lang.ArrayIndexOutOfBoundsException : 99
    methodeB : execute finally
    methodeB : fin
  methodeA : retour de methodeB
  methodeA : execute finally
  methodeA : fin
main : retour de methodeA
main : fin
  • les lignes de la classe :
    • l'exception ArrayIndexOutOfBoundsException est capturée par la méthodeB donc la méthodeA se déroule normalement
    • les post-traitements finally sont exécutés à chaque fois
  
Source de Except2.java
import java.io.*;
public class Except2 {
  public static void main(String args[]) {
    System.out.println("main : debut");
    Except2 ex = new Except2();
    try {
      System.out.println("main : appel de methodeA");
      ex.methodeA(args);
      System.out.println("main : retour de methodeA");
    } catch (Exception e) {
      System.out.println("main : catch une Exception : "+e);
    }
    System.out.println("main : fin");
  }
  public void methodeA(String args[]) {
    System.out.println("  methodeA : debut");
    try {
      System.out.println("  methodeA : appel de methodeC");
      this.methodeC(args);
      System.out.println("  methodeA : retour de methodeC");
      if (args.length > 99)
        throw new IOException();
    } catch (IOException e) {
      System.out.println("  methodeA : catch une Exception : "+ e);
    } finally {
      System.out.println("  methodeA : execute finally");
    }
    System.out.println("  methodeA : fin");
  }
  public void methodeC(String args[]) {
    System.out.println("    methodeC : debut");
    try {
      System.out.println("    methodeC : tente d'acceder a args[99]");
      String s = args[99];
      System.out.println("    methodeC : a reussi a acceder a args[99]");
    } finally {
      System.out.println("    methodeC : execute finally");
    }
    System.out.println("    methodeC : fin");
  }
}
EXECUTION
$ java Except2
main : debut
main : appel de methodeA
  methodeA : debut
  methodeA : appel de methodeC
    methodeC : debut
    methodeC : tente d'acceder a args[99]
    methodeC : execute finally
  methodeA : execute finally
main : catch une Exception : 
      java.lang.ArrayIndexOutOfBoundsException : 99
main : fin
  • les lignes de la classe :
    • l'exception ArrayIndexOutOfBoundsException n'est pas contrôllée donc ne nécessite pas obligatoirement de capture (try) ou de propagation (throws)
    • elle provoque l'arret du bloc try dans la méthodeC, et comme il n'y a pas de catch, l'exécution passe au post-traitement finally
    • Elle n'est pas capturée par la méthodeA car elle n'est pas une IOException, donc elle est propagée à  main
    • elle est capturée dans le bloc de main en tant qu'Exception
  
Source de Except3.java
import java.io.*;
public class Except3 {
  public static void main(String args[]) {
    System.out.println("main : debut");
    Except3 ex = new Except3();
    try {
      System.out.println("main : appel de methodeA");
      ex.methodeA(args);
      System.out.println("main : retour de methodeA");
    } catch (Exception e) {
      System.out.println("main : catch une Exception : "+e);
    }
    System.out.println("main : fin");
  }
  public void methodeA(String args[]) {
    System.out.println("  methodeA : debut");
    try {
      System.out.println("  methodeA : appel de methodeD");
      this.methodeD(args);
      System.out.println("  methodeA : retour de methodeD");
    } catch (IOException e) {
      System.out.println("  methodeA : catch une Exception : "+ e);
    } finally {
      System.out.println("  methodeA : execute finally");
    }
    System.out.println("  methodeA : fin");
  }
  public void methodeD(String args[]) 
         throws  IOException {
    System.out.println("    methodeD : debut");
    try {
      System.out.println("    methodeD : tente d'ouvrir fichierExistePas");
      FileReader f = new FileReader("fichierExistePas");
      System.out.println("    methodeD : a reussi a ouvrir fichierExistePas");
    } finally {
      System.out.println("    methodeD : execute finally");
    }
    System.out.println("    methodeD : fin");
  }
}
EXECUTION
$ java Except3     
main : debut
main : appel de methodeA
  methodeA : debut
  methodeA : appel de methodeD
    methodeD : debut
    methodeD : tente d'ouvrir fichierExistePas
    methodeD : execute finally
  methodeA : catch une Exception : java.io.FileNotFoundException: 
                   fichierExistePas (No such file or directory)
  methodeA : execute finally
  methodeA : fin
main : retour de methodeA
main : fin
  • les lignes de la classe :
    • l'exception java.io.FileNotFoundException arrête le bloc dans la méthodeD,
    • n'est pas capturée (catch) dans cette méthode,
    • exécute finally (qui ne capture pas !).
    • Elle est finallement capturée dans la méthodeA.

Définition de try-catch-finally

exception dans une application

Source de AppliBienVendue.java
import java.io.*;
public class AppliBienVendue {
  public static void main(String args[]) {
    System.out.println("-- AppliBienVendue --\n"
                  +" bienvenue tres cher client");
    AppliBienVendue ex = new AppliBienVendue();
    System.out.println("main : debut");
    FileOutputStream appliLog = null;
    BufferedOutputStream buffLog = null;
    try {
      appliLog = new FileOutputStream ("fichierAppliLog");
      buffLog = new BufferedOutputStream(appliLog);
      moduleChere1(args);
      moduleChere2(args);
    } catch (IOException e) {
      System.out.println("une erreur de VOTRE materiel s'est produite\n"
                    +" Appelez notre hot-line au 08 5 euros la minute" );
      e.printStackTrace(new PrintStream(buffLog)); 
      try {
        buffLog.close();
      } catch (IOException e2) {}
    }
    System.out.println("main : fin");
  }
  public static void moduleChere1(String args[])  {
    System.out.println("  moduleChere1 : debut");
    try {
      System.out.println("  moduleChere1 : tente d'acceder a args[99]");
      String s = args[99];
      System.out.println("  moduleChere1 : a reussi a acceder a args[99]");
    } catch (ArrayIndexOutOfBoundsException e) {
      System.out.println("  moduleChere1 : catch une Exception "
                        +" facile a traiter "+ e);
    } finally {
      System.out.println("  moduleChere1 :  finally : cool ! ");
    }
    System.out.println("  moduleChere1 : fin");
  }
  public static void moduleChere2(String args[]) 
         throws  IOException {
    System.out.println("  moduleChere2 : debut");
    try {
      System.out.println("  moduleChere2 : tente d'ouvrir fichierExistePas");
      FileReader f = new FileReader("fichierExistePas");
      System.out.println("  moduleChere2 : a reussi a ouvrir fichierExistePas");
    } finally {
      System.out.println("  moduleChere2 : finally : "
                   +"essaye de fermer proprement");
    }
    System.out.println("  moduleChere2 : fin");
  }
}
EXECUTION
$ java AppliBienVendue     
-- AppliBienVendue --
 bienvenue tres cher client
main : debut
  moduleChere1 : debut
  moduleChere1 : tente d'acceder a args[99]
  moduleChere1 : catch une Exception  facile a traiter                   
                 java.lang.ArrayIndexOutOfBoundsException: 99
  moduleChere1 :  finally : cool ! 
  moduleChere1 : fin
    moduleChere2 : debut
    moduleChere2 : tente d'ouvrir fichierExistePas
    moduleChere2 : finally : essaye de fermer proprement
                   une erreur de VOTRE materiel s'est produite
 Appelez notre hot-line au 08 5 euros la minute
main : fin
  
$ cat fichierAppliLog
java.io.FileNotFoundException: fichierExistePas (No such file or directory)
        at java.io.FileInputStream.open(Native Method)
        at java.io.FileInputStream.<init>(FileInputStream.java:106)
        at java.io.FileInputStream.<init>(FileInputStream.java:66)
        at java.io.FileReader.<init>(FileReader.java:41)
        at AppliBienVendue.moduleChere2(AppliBienVendue.java:45)
        at AppliBienVendue.main(AppliBienVendue.java:15)
  • les lignes de la classe :
    • les exceptions qui n'entrainent pas d'arret de l'application sont traitées
    • les exceptions fatales ou imprévisibles donc intraitables envoient un message poli au client et logguent les erreurs.
    • La méthode printStackTrace() affiche une trace de la pile au moment de la levée de l'exception dans le fichier log
    • Il est possible (içi, pour clos, nécessaire) d'imbriquer un bloc try dans les clauses try, catch et finally d'un autre.

exception dans les constructeurs

Source de Toutou.java
source
EXECUTION
$ java Toutou     
creation d'un premier toutou
le voici : milou aboie waouah et a 4 puces.
creation d'un second toutou
un toutou rate !! java.lang.IllegalArgumentException:
                 nombre negatif de puces !
  • les lignes de la classe :
    • l'objet Toutou n'est pas construit si ses paramètres de création sont incohérents

try-catch-finally contre return-break-continue

Source de Except4.java
public class Except4 {
  public static void main(String args[]) {
    Except4 ex = new Except4();
    System.out.println("main : methodeA retourne : "
                      + ex.methodeA());
    System.out.println("main : methodeB retourne : "
                      + ex.methodeB());
  }
  public String methodeA() {
    try {
      return "sortie bloc try";
    }
    catch  (Exception e) {
      return "sortie bloc catch";
    }
  }
  public String methodeB() {
    try {
      return "sortie bloc try";
    }
    finally {
      return "sortie bloc finally";
    }
  }
}
EXECUTION
$ java Except4     
main : methodeA retourne : sortie bloc try
main : methodeB retourne : sortie bloc finally
  • les lignes de la classe :
    • un return de bloc try est recouvert par un return de bloc catch ou de bloc finally

exercices