Menu
Coddy logo textTech

Gerarchia delle classi di eccezione

Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 59 di 87.

Il sistema di gestione delle eccezioni di Java si basa su una gerarchia di classi ben organizzata, che ha come radice la classe Throwable. Comprendere questa gerarchia ti aiuta a intercettare e gestire le eccezioni in modo più efficace.

In cima si trova Throwable, la classe genitore di tutte le eccezioni e gli errori. Ha due sottoclassi dirette:

Throwable
├── Error          // Problemi gravi (non intercettarli)
└── Exception      // Problemi recuperabili
    └── RuntimeException  // Eccezioni non controllate

Errore rappresenta problemi gravi che le applicazioni non dovrebbero cercare di gestire, come OutOfMemoryError o StackOverflowError. Questi indicano problemi fondamentali della JVM stessa.

Exception è il ramo con cui lavorerai più spesso. Si divide in due categorie: eccezioni verificate (sottoclassi dirette di Exception) ed eccezioni non verificate (sottoclassi di RuntimeException).

// Classi di eccezioni comuni
Exception
├── IOException           // Problemi relativi a file e rete
├── SQLException          // Problemi relativi al database
└── RuntimeException
    ├── NullPointerException
    ├── ArrayIndexOutOfBoundsException
    └── IllegalArgumentException

Poiché le eccezioni sono classi, seguono le regole dell’ereditarietà. Quando catturi un tipo di eccezione genitore, catturi anche tutti i suoi tipi derivati:

try {
    // del codice
} catch (Exception e) {
    // Cattura TUTTE le eccezioni (di solito troppo generico)
}
try {
    // del codice
} catch (RuntimeException e) {
    // Intercetta solo le eccezioni di runtime e le relative sottoclassi
}

Questa gerarchia ti permette di essere specifico o generico quanto necessario nella gestione degli errori ed è la base per creare eccezioni personalizzate.

challenge icon

Sfida

Facile

Costruiamo un analizzatore di eccezioni che mostra come funziona in pratica la gerarchia delle eccezioni di Java! Creerai un sistema che intercetta le eccezioni a diversi livelli di specificità e segnala quale tipo è stato intercettato.

Organizzerai il codice in tre file:

  • ExceptionThrower.java: crea una classe in grado di generare diversi tipi di eccezioni in base all'input. La classe deve avere tre metodi statici:

    triggerRuntime(String type) - In base alla stringa type, genera diverse eccezioni runtime:

    • Se type è "null", genera una NullPointerException con il messaggio "Null value encountered"
    • Se type è "index", genera una ArrayIndexOutOfBoundsException con il messaggio "Invalid index"
    • Se type è "argument", genera una IllegalArgumentException con il messaggio "Bad argument"

    triggerArithmetic() - Genera una ArithmeticException con il messaggio "Division error"

    triggerGeneric() - Genera una IllegalStateException con il messaggio "Generic runtime error" (la sua gerarchia è Exception > RuntimeException > IllegalStateException)

  • ExceptionAnalyzer.java: crea una classe che intercetta le eccezioni a diversi livelli della gerarchia e identifica quale è stata intercettata. Includi questi metodi statici:

    analyzeSpecific(String type) - Chiama ExceptionThrower.triggerRuntime(type) all'interno di un blocco try. Usa blocchi catch separati per NullPointerException, ArrayIndexOutOfBoundsException e IllegalArgumentException. Per ciascuna, stampa: Caught specific: [exception class simple name] seguito da Message: [exception message]

    analyzeWithParent() - Chiama ExceptionThrower.triggerArithmetic() all'interno di un blocco try. Intercettala usando RuntimeException (il tipo genitore). Stampa: Caught via parent: RuntimeException seguito da Actual type: [exception class simple name]

    analyzeWithGrandparent() - Chiama ExceptionThrower.triggerGeneric() all'interno di un blocco try. Intercettala usando Exception (un livello ancora più alto nella gerarchia). Stampa: Caught via grandparent: Exception seguito da Actual type: [exception class simple name]

  • Main.java: metti insieme il tuo analizzatore di eccezioni! Riceverai un input: una stringa che indica il tipo di eccezione (ovvero "null", "index" oppure "argument").

    Per prima cosa, stampa === Specific Catch === e chiama analyzeSpecific con il tuo input.

    Poi stampa una riga vuota, === Parent Catch === e chiama analyzeWithParent.

    Infine, stampa una riga vuota, === Grandparent Catch === e chiama analyzeWithGrandparent.

Riceverai un input: il tipo di eccezione da generare ("null", "index" oppure "argument").

Usa e.getClass().getSimpleName() per ottenere il nome della classe dell'eccezione e e.getMessage() per recuperarne il messaggio. Questa sfida mostra come intercettare un tipo di eccezione genitore significhi intercettare anche tutti i suoi tipi derivati: un concetto fondamentale per decidere quanto debba essere specifica la gestione delle eccezioni!

Provalo tu

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String type = scanner.nextLine();
        
        // TODO: Stampa "=== Specific Catch ===" e chiama ExceptionAnalyzer.analyzeSpecific(type)
        
        // TODO: Stampa una riga vuota, poi "=== Parent Catch ===", quindi chiama ExceptionAnalyzer.analyzeWithParent()
        
        // TODO: Stampa una riga vuota, poi "=== Grandparent Catch ===", quindi chiama ExceptionAnalyzer.analyzeWithGrandparent()
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Java online