martedì 9 aprile 2013

Eccezioni



Una eccezione è una situazione imprevista che il flusso di un’applicazione può incontrare e che può essere gestita.
Un errore è una situazione imprevista non dipendente da un errore commesso dallo sviluppatore e non può essere gestito.

Errori ed eccezioni derivano da Throwable.
Tutti gli Errori derivano da Error.
Tutte le eccezioni derivano da Exception.

Se JAVA si imbatte in un'eccezione la "lancia", interrompendo l'esecuzione e stampando a video l'errore:

public class Principale {
     public static void main(String[] args) {
         int a=1;
         int b=0;
         System.out.println(a/b);
     }
}

Exception in thread "main" java.lang.ArithmeticException: / by zero
     at Principale.main(Principale.java:5)

L’eccezione può essere gestita con un try catch :

         try {
         System.out.println(a/b);  
         }
         catch (ArithmeticException exc) {
              System.out.println("Divisione per ZERO");
         }
         }
L’eccezione dichiarata (ArithmeticException) deve essere quella giusta altrimenti il catch non la cattura.
Le eccezioni sono polimorfe e quindi si può dichiarare e catturare una eccezione superiore :
         try {
         System.out.println(a/b);  
         }
         catch (Exception exc) {
              System.out.println("eccezione generica");
         }
         }
Si possono dichiarare varie eccezioni e così discrimnare la gestione a seconda dell’eccezione catturata:
         try {
         System.out.println(a/b);  
         }
         catch (ArithmeticException exc) {
              System.out.println("Divisione per ZERO ");
         }
         catch (NullPointerException exc) {
              System.out.println("riferimento nullo");
         }
         catch (Exception exc) {
              System.out.println("eccezione generica");
         }
In questo caso l’ordine è importante, il catch che entra in azione è quello scritto per primo.

finally indica un blocco che deve essere sempre eseguito, sia se c’è una eccezione oppure no :
         try {
         System.out.println(a/b);  
         }
         catch (ArithmeticException exc) {
              System.out.println("divisione per zero");
         }
         catch (NullPointerException exc) {
              System.out.println("riferimento nullo");
         }
         catch (Exception exc) {
              System.out.println("eccezione generica");
         }
         finally { System.out.println("Tentativo di operazione"); }

Eccezione personalizzata :
public class PersonalizzataException extends Exception {
     public PersonalizzataException() {
         super("Problema personalizzato");
     }
     public String toString() {
         return getMessage() + ": messaggio personalizzato";
     }
}
si lancia in modo diretto:
public class Principale {
     public static void main(String[] args) throws PersonalizzataException {
         boolean controllo = true;      
         if (controllo){
              PersonalizzataException eccezione = new PersonalizzataException();
              throw eccezione;
         }
     }
}
Si può anche scrivere in modo compatto:  throw new PersonalizzataException();
e si ottiene:
Exception in thread "main" Problema personalizzato: messaggio personalizzato
     at Principale.main(Principale.java:5)

Perché creare eccezioni personalizzate? Consideriamo questo codice :
public class ClasseProblematica {
     public ClasseProblematica(int a) {
         try {
              metodo(a);
         } catch (PersonalizzataException e) {
              System.out.println("errore gravissimo!!!");
         }
     }
     public void metodo(int a) throws PersonalizzataException {
         if (a > 1) {
              throw new PersonalizzataException();
         }
     }

}
public class PersonalizzataException extends Exception {
     public PersonalizzataException() {
         super("Problema personalizzato");
     }
     public String toString() {
         return getMessage() + ": messaggio personalizzato";
     }
}
public class Principale {
     public static void main(String[] args) {
         for (int i = 0;i<3;i++){
              ClasseProblematica cp = new ClasseProblematica(i);
              System.out.println("tutto benissimo con "+i);
         }
        
     }
}

In questo caso pur catturando l’eccezione nel metodo il risultato non è buono perché si prosegue nell’elaborazione:
tutto benissimo con 0
tutto benissimo con 1
errore gravissimo!!!
tutto benissimo con 2
A questo punto entra in campo la forza di JAVA, consentendo la propagazione dell’eccezione; l’eccezione non deve essere catturata per forza dove si produce ma anche esternamente, consentendo una gestione molto migliore del flusso di lavoro:
public class ClasseProblematica {
     public ClasseProblematica(int a) throws PersonalizzataException{
      metodo(a);

     }
     public void metodo(int a) throws PersonalizzataException {
         if (a > 1) {
              throw new PersonalizzataException();
         }
     }

}
public class Principale {
     public static void main(String[] args) {
         for (int i = 0; i < 3; i++) {
              try {
                  ClasseProblematica cp = new ClasseProblematica(i);
                  System.out.println("tutto benissimo con " + i);
              } catch (PersonalizzataException e) {
                  System.out.println("errore gravissimo!!!");
              }
             
         }

     }
}
tutto benissimo con 0
tutto benissimo con 1
errore gravissimo!!!

Con la clausola throws nella dichiarazione del metodo, in pratica è come se avvertissimo il compilatore che siamo consapevoli che il metodo possa lanciare al runtime la PersonalizzataException, e di non “preoccuparsi”, perché gestiremo in un’altra parte del codice l’eccezione. Se un metodo “chiamante” vuole utilizzare un altro metodo “daChiamare” che dichiara con una clausola throws il possibile lancio di un certo tipo di eccezione, allora, il metodo “chiamante”, o deve gestire l’eccezione con un blocco try – catch che include la chiamata al metodo “daChiamare”, o deve dichiarare anch’esso una clausola throws alla stessa eccezione.




Nessun commento:

Posta un commento