back to top

Gestire le eccezioni in Java: il blocco try-catch

Entriamo subito nel vivo della trattazione per quanto riguarda il costrutto try e catch. Praticamente nel blocco try deve essere inserito il pezzo di codice che potrebbe generare un’eventuale eccezione e nel blocco catch il codice di gestione dell’eccezione (come per esempio una stampa a video che notifichi all’utente che si è verificato un errore). Vediamo adesso come modificare la classe "Implementazione" vista in uno degli esempi precedenti:

public class Implementazione {

  public static void main(String args[]) {
    
    int divisione;
    
    OperazioniSuNumeri operazioni = new OperazioniSuNumeri();
    
    try {
      divisione = operazioni.divisione(5,0);
      System.out.println("Il risultato della divisione è:" + divisione);
    }

    catch (Exception exc) {
      System.out.println(exc);
      System.out.println("Non puoi effettuare una divisione per zero");
    }
    
    System.out.println("Ho terminato comunque l'esecuzione del programma");
    
  }
}

Come abbiamo detto il metodo "divisione", che può generare un’eccezione, è stato inserito all’interno del blocco try. Se il metodo non solleva un’eccezione si passerà alla stampa del risultato della divisione, altrimenti si passarà ad eseguire il codice contenuto nel blocco catch.

Andiamo adesso ad analizzare la sintassi di catch (Exception exc). Il costrutto è dunque formato dalla parola chiave catch ed un parametro tra parentesi del tipo Exception. La parte identificata da exc non è altro che una variabile di tipo Exception nella quale viene inserito il messaggio di errore relativo all’eccezione sollevata. Nel caso in cui lanciassimo la classe "Implementazione", a video vedremo la seguente stampa:

java.lang.ArithmeticException: / by zero
Non puoi effettuare una divisione per zero
Ho terminato comunque l'esecuzione del programma

La prima riga rappresenta la stampa relativa alla variabile exc, la seconda al nostro messaggio di errore e la terza alla stampa relativa a fine applicazione. Costituisce aspetto particolare proprio questa ultima stampa dato che adesso, gestendo l’eccezione, abbiamo permesso all’applicazione di terminare la sua esecuzione in maniera corretta senza una terminazione prematura. Nel nostro caso inserendo come parametro di catch il tipo Exception avremo comunque catturato qualsiasi eccezione che si fosse generata, anche un’eccezione sollevata dalla JMV in caso avessimo chiamato un generico metodo su di un reference che non era stato inizializzato e quindi che puntava a null (nel nostro esempio ciò non può accadere).

Dunque è buona norma gestire le eccezioni catturandole separatamente e ciò può essere ottenuto utilizzando più blocchi catch uno dopo l’altro. Vediamo adesso come compiere questa miglioria sfruttando sempre la nostra classe Implementazione:

try {
 divisione = operazioni.divisione(5,0);
 System.out.println("Il risultato della divisione è:" + divisione);
}
    
catch (ArithmeticException exc) {
  System.out.println(exc);
  System.out.println("Non puoi effettuare una divisione per zero");
}
        
catch (Exception exc) {
  System.out.println("Errore generico");
}

In questo modo quando viene generata un’eccezione la JVM andrà a controllare i vari blocchi catch. I blocchi vengono scorsi tutti fino a che non viene trovato quello che gestisce quel particolare tipo di eccezione e quindi viene eseguito il codice all’interno del catch relativo.

Nel nostro esempio dunque se viene generata un’eccezione di tipo AritmeticException verrà eseguito il codice del primo blocco catch. Nel caso in cui avessimo avuto un altro tipo di eccezione dunque la JVM sarebbe passata oltre al catch relativo all’AritmeticException ed avrebbe eseguito il codice all’interno il secondo catch. L’ordine con i quali devono essere scritti i catch è importante in quanto devono essere scritti da quello meno generale a quello più generale. Infatti nel caso avessimo invertito l’ordine dei due catch nel codice d’esempio l’eccezione sarebbe stata catturata automaticamente dal blocco più generale Exception senza mai raggiungere il catch relativo alla gestione specifica dell’AritmeticException. Il fatto di poter gestire in maniera separata i vari tipi di eccezione, permette al programmatore di capire immediatamente quale punto del codice ha generato l’eccezione e cosa di preciso è andato storto.

Pubblicità