Clausole catch Multiple in Java

Concetti Chiave
  • Le clausole catch multiple in Java consentono di gestire diversi tipi di eccezioni in un singolo blocco try.
  • È possibile specificare più clausole catch per intercettare diversi tipi di eccezioni, e l'ordine delle clausole è importante per evitare errori di codice irraggiungibile.
  • Le eccezioni sottoclasse devono essere specificate prima delle loro superclassi nelle clausole catch, altrimenti si verificherà un errore di compilazione.
  • Quando si intercettano più eccezioni, il programma esegue la prima clausola catch il cui tipo corrisponde all'eccezione sollevata.

Clausole catch multiple

In alcuni casi, più di un'eccezione può essere sollevata da una singola istruzione di codice.

Per gestire questo tipo di situazione, si possono specificare due o più clausole catch, ognuna delle quali intercetta un diverso tipo di eccezione.

Quando viene sollevata un'eccezione, ogni istruzione catch viene ispezionata in ordine, e viene eseguita la prima il cui tipo corrisponde a quello dell'eccezione. Una volta eseguita un'istruzione catch, le altre vengono saltate, ed esecuzione continua dopo i blocchi try / catch. Il seguente esempio intercetta due diversi tipi di eccezioni:

// Dimostrazione di più istruzioni catch.
class EccezioniMultiple {
    public static void main(String[] args) {
        try {
            int a = args.length;
            System.out.println("a = " + a);
            int b = 42 / a;
            int[] c = { 1 };
            c[42] = 99;
        } catch (ArithmeticException e) {
            System.out.println("Divisione per 0: " + e);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("Indice array fuori limite: " + e);
        }
        System.out.println("Dopo i blocchi try/catch.");
    }
}

Questo programma genererà un'eccezione di divisione per zero se viene avviato senza argomenti da riga di comando, poiché a sarà uguale a zero.

Supererà la divisione se si fornisce un argomento da riga di comando, impostando a a un valore maggiore di zero. Ma ciò causerà un'ArrayIndexOutOfBoundsException, poiché l'array c ha lunghezza 1, e tuttavia il programma tenta di assegnare un valore a c[42].

Ecco l'output generato eseguendolo in entrambi i modi:

$ java EccezioniMultiple
a = 0
Divisione per 0: java.lang.ArithmeticException: / by zero
Dopo i blocchi try/catch.

$ java EccezioniMultiple ArgomentoTest
a = 1
Indice array fuori limite: java.lang.ArrayIndexOutOfBoundsException:
Index 42 out of bounds for length 1
Dopo i blocchi try/catch.

Quando si usano più istruzioni catch, è importante ricordare che le eccezioni sottoclasse devono venire prima delle loro superclasse.

Questo perché un'istruzione catch che usa una superclasse intercetterà tutte le eccezioni di quel tipo più tutte le sue sottoclassi. Quindi, una sottoclasse non verrebbe mai raggiunta se venisse dopo la sua superclasse. Inoltre, in Java, il codice irraggiungibile è considerato un errore. Ad esempio, si consideri il seguente programma:

/* Questo programma contiene un errore.

Una sottoclasse deve venire prima della sua superclasse
in una serie di istruzioni catch. Altrimenti,
verrà creato codice irraggiungibile e si verificherà
un errore in fase di compilazione.
*/
class SuperSottoCatch {
    public static void main(String[] args) {
        try {
            int a = 0;
            int b = 42 / a;
        } catch (Exception e) {
            System.out.println("Eccezione generica catch.");
        }
        /* Questo catch non viene mai raggiunto perché
        ArithmeticException è una sottoclasse di Exception. */
        catch (ArithmeticException e) {
            // ERRORE - irraggiungibile
            System.out.println("Questo non viene mai raggiunto.");
        }
    }
}
Nota

Ordine delle eccezioni nel blocco catch

Se si tenta di compilare questo programma, verrà visualizzato un messaggio di errore che indica che la seconda istruzione catch è irraggiungibile perché l'eccezione è già stata intercettata.

Poiché ArithmeticException è una sottoclasse di Exception, la prima istruzione catch intercetterà tutti gli errori basati su Exception, inclusa ArithmeticException. Questo significa che la seconda istruzione catch non verrà mai eseguita. Per risolvere il problema, bisogna invertire l'ordine delle istruzioni catch.