Il corretto uso delle eccezioni verificate e non verificate – Lezione 2 di Java Avanzato

Eccezioni: differenza tra verificate e non verificata

Abbiamo già parlato di eccezioni in Java, il meccanismo che permette di gestire gli eventuali errori durante l’esecuzione di un programma. Le eccezioni vengono suddivise in eccezioni verificate e non verificata: le prime si riferiscono al fatto che il compilatore verifica se tali eccezioni sono opportunamente trattate dal programmatore; al contrario, quelle non verificate sono ad uso libero dello sviluppatore.

Approfondiamo il discorso, vediamo esattamente come si comporta il compilatore quando incontra un’eccezione verificata. Se abbiamo un oggetto x che invoca un metodo f:

  x.f();

Per un corretto funzionamento il compilatore dovrebbe analizzare tutto il corpo di f() per controllare se ci potrebbe essere il lancio di un’eccezione… quest’operazione sarebbe molto lunga e dispendiosa, si dovrebbero controllare tutti i metodi del programma alla ricerca di eccezioni. In termini di costi e tempo sarebbe disastroso!
A tale scopo è stata introdotta in Java la possibilità di poter dichiarare le eccezioni, il programmatore che ha scritto il codice sa se un metodo potrebbe lanciare un’eccezione e di conseguenza la può dichiarare tramite la clausola throws. La clausola throws può essere usata sia per le eccezioni verificate che per quelle non verificate, ma è buona norma utilizzarla solo per quelle di tipo verificato.

  public void f() throws RuntimeException {
    // Codice che potrebbe lanciare RuntimeException
  }

Eccezioni verificate e non verificate

Quando si vuole creare un nuovo tipo di eccezione, bisogna scegliere se crearle di tipo verificato (checked) o non verificato (unchecked). Sapendo che le eccezioni devono essere di tipo verificato se il programmatore non può avere la certezza di evitarle e che richiedono un opportuno trattamento, possiamo definire una semplice linea guida per aiutarci nelle nostre scelte:

“Se l’anomalia poteva essere evitata dal chiamante, è consigliato usare le eccezioni non verificate”

Facciamo degli esempi:

  1. Il metodo Stampa vuole stampare dei file ma la carta è finita; il chiamante poteva evitarlo? No, perché il chiamante non può verificare la presenza o meno della carta;
  2. Un metodo tenta di aprire un file ma non esiste; poteva essere evitato? No, anche se il chiamante avesse verificato l’esistenza del file prima di invocare il metodo, nulla vieta che un metodo in un altro metodo l’abbia cancellato immediatamente dopo la verifica. Pertanto, l’eccezione FileNotFoundException è verificata;
  3. Memoria esaurita; il chiamante può verificarlo in anticipo? In un certo qual modo la risposta è si, ma questo significherebbe che ogni volte che usiamo una new per creare nuovi oggetti dovremmo gestirli con dei try-catch. Nel caso di riposta negativa il programmatore non potrebbe fare molto se non terminare il programma, per cui è di tipo non verificato. Si tratta di OutOfMemoryError;
  4. Accesso ad un array con un indice non valido. Si tratta di un errore di programmazione, poteva essere evitato. Inoltre, ad ogni accesso ad un array si dovrebbe usare un try/cath. Quest’eccezione non verificata è conosciuta come ArrayOutOfBoundsException. Vediamo un codice d’esempio:

    Codice esempio di ArrayOutOfBoundsException - Datrevo

    Abbiamo creato un array con 5 elementi e vogliamo stampare il sesto elemento dell’array (ricordiamoci che gli indici in Java partono da zero). Il programma lancerà un’eccezione perchè si tratta di un errore di programmazione, può essere facilmente evitato prestando più attenzione:

    Esempio di ArrayOutOfBoundsException - Datrevo
  5. L’argomento passato al calcolo della radice quadrata è negativo; eccezione non verificata, può essere evitato con un semplice controllo sul segno.

Le linee guide, in linea di massima, non sono mai esaustive… non valgono per tutti i casi possibili. Ad esempio se un metodo accede al campo Offset di un file e vi trova un valore negativo, non è colpa del chiamante, si tratta di un problema esterno alla classe stessa quindi si tratta di un’eccezione non verificata.

Indice Lezione PrecedenteLezione Successiva

Pubblicato in Guide, Java, Programmazione Taggato con: , , , ,

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

*