Eccezioni Built-in e Eccezioni Personalizzate in Java
- Java fornisce un sistema di gestione delle eccezioni che consente di gestire gli errori in modo strutturato.
- Le eccezioni in Java sono rappresentate da classi che estendono
Throwable
, con due principali sottoclassi:Exception
eError
. - Le eccezioni possono essere controllate (checked) o non controllate (unchecked), a seconda che debbano essere dichiarate nella firma del metodo.
- È possibile creare eccezioni personalizzate estendendo la classe
Exception
oRuntimeException
.
Eccezioni Predefinite di Java
All'interno del pacchetto standard java.lang
, Java definisce diverse classi di eccezioni.
Alcune sono state utilizzate negli esempi precedenti. Le più generali tra queste eccezioni sono sottoclassi del tipo standard RuntimeException
. Come spiegato in precedenza, queste eccezioni non devono essere incluse nella lista throws
di un metodo.
Nel linguaggio di Java, queste sono chiamate eccezioni non controllate (unchecked exceptions) perché il compilatore non verifica se un metodo le gestisce o le lancia.
Le eccezioni non controllate definite in java.lang
sono elencate nella Tabella seguente:
Eccezione | Significato |
---|---|
ArithmeticException |
Errore aritmetico, come divisione per zero. |
ArrayIndexOutOfBoundsException |
Indice dell'array fuori dai limiti. |
ArrayStoreException |
Assegnazione a un elemento di un array di un tipo incompatibile. |
ClassCastException |
Cast non valido. |
EnumConstantNotPresentException |
Si tenta di usare un valore di enumerazione non definito. |
IllegalArgumentException |
Argomento non valido usato per invocare un metodo. |
IllegalCallerException |
Un metodo non può essere eseguito legalmente dal codice chiamante. |
IllegalMonitorStateException |
Operazione illegale di monitoraggio, come attendere su un thread non bloccato. |
IllegalStateException |
Ambiente o applicazione in stato non corretto. |
IllegalThreadStateException |
Operazione richiesta non compatibile con lo stato corrente del thread. |
IndexOutOfBoundsException |
Alcun tipo di indice è fuori dai limiti. |
LayerInstantiationException |
Un layer del modulo non può essere creato. |
NegativeArraySizeException |
Array creato con una dimensione negativa. |
NullPointerException |
Uso non valido di un riferimento null. |
NumberFormatException |
Conversione non valida di una stringa in formato numerico. |
SecurityException |
Tentativo di violare la sicurezza. |
StringIndexOutOfBoundsException |
Tentativo di accedere oltre i limiti di una stringa. |
TypeNotPresentException |
Tipo non trovato. |
UnsupportedOperationException |
È stata incontrata un'operazione non supportata. |
La Tabella che segue, invece, elenca le eccezioni definite da java.lang
che devono essere incluse nella lista throws
di un metodo se tale metodo può generare una di queste eccezioni e non le gestisce autonomamente. Queste sono chiamate eccezioni controllate (checked exceptions). Oltre alle eccezioni presenti in java.lang
, Java ne definisce molte altre che si riferiscono ai suoi altri pacchetti standard.
Eccezione | Significato |
---|---|
ClassNotFoundException |
Classe non trovata. |
CloneNotSupportedException |
Tentativo di clonare un oggetto che non implementa l'interfaccia Cloneable . |
IllegalAccessException |
Accesso a una classe negato. |
InstantiationException |
Tentativo di creare un oggetto da una classe o interfaccia astratta. |
InterruptedException |
Un thread è stato interrotto da un altro thread. |
NoSuchFieldException |
Un campo richiesto non esiste. |
NoSuchMethodException |
Un metodo richiesto non esiste. |
ReflectiveOperationException |
Superclasse delle eccezioni relative alla riflessione. |
Creare le Proprie Sottoclassi di Eccezione
Sebbene le eccezioni predefinite di Java gestiscano la maggior parte degli errori comuni, probabilmente sarà necessario creare propri tipi di eccezione per gestire situazioni specifiche delle applicazioni.
Questo è piuttosto semplice: basta definire una sottoclasse di Exception
(che è, ovviamente, una sottoclasse di Throwable
). Le sottoclassi non devono implementare necessariamente nulla: è la loro esistenza nel sistema di tipi che consente di usarle come eccezioni.
La classe Exception
non definisce alcun metodo proprio. Eredita però, ovviamente, i metodi forniti da Throwable
. Pertanto, tutte le eccezioni, incluse quelle create, dispongono dei metodi definiti da Throwable
. Questi sono mostrati nella Tabella che segue. È anche possibile voler sovrascrivere uno o più di questi metodi nelle classi di eccezione che si creano.
Metodo | Descrizione |
---|---|
final void addSuppressed(Throwable exc) |
Aggiunge exc all'elenco delle eccezioni soppresse associate all'eccezione chiamante. Utilizzato principalmente con l'istruzione try-with-resources . |
Throwable fillInStackTrace() |
Restituisce un oggetto Throwable che contiene un stack trace completo. Questo oggetto può essere rilanciato. |
Throwable getCause() |
Restituisce l'eccezione che ha causato l'eccezione corrente. Se non c'è una causa sottostante, viene restituito null . |
String getLocalizedMessage() |
Restituisce una descrizione localizzata dell'eccezione. |
String getMessage() |
Restituisce una descrizione dell'eccezione. |
StackTraceElement[ ] getStackTrace() |
Restituisce un array contenente lo stack trace, un elemento alla volta, come array di StackTraceElement . Il metodo in cima allo stack è l'ultimo chiamato prima che l'eccezione fosse lanciata. Questo metodo si trova nel primo elemento dell'array. La classe StackTraceElement fornisce al programma accesso alle informazioni su ciascun elemento dello stack, come il nome del metodo. |
final Throwable[ ] getSuppressed() |
Ottiene le eccezioni soppresse associate all'eccezione chiamante e restituisce un array con il risultato. Le eccezioni soppresse sono generate principalmente con l'istruzione try-with-resources . |
Throwable initCause(Throwable causeExc) |
Associa causeExc con l'eccezione chiamante come causa della stessa. Restituisce un riferimento all'eccezione. |
void printStackTrace() |
Visualizza lo stack trace. |
void printStackTrace(PrintStream stream) |
Invia lo stack trace allo stream specificato. |
void printStackTrace(PrintWriter stream) |
Invia lo stack trace allo stream specificato. |
void setStackTrace(StackTraceElement[ ] elements) |
Imposta lo stack trace sugli elementi passati in elements . Questo metodo è destinato ad applicazioni specializzate, non all'uso normale. |
String toString() |
Restituisce un oggetto String contenente una descrizione dell'eccezione. Questo metodo è chiamato da println() quando si stampa un oggetto Throwable . |
Exception
definisce quattro costruttori pubblici. Due supportano le eccezioni concatenate, descritte nella sezione successiva. Gli altri due sono mostrati qui:
Exception( )
Exception(String msg)
Il primo costruttore crea un'eccezione senza descrizione. Il secondo consente di specificare una descrizione dell'eccezione.
Anche se specificare una descrizione quando si crea un'eccezione è spesso utile, a volte è meglio sovrascrivere toString()
. Ecco perché: la versione di toString()
definita da Throwable
(ed ereditata da Exception
) mostra prima il nome dell'eccezione seguito da due punti, quindi dalla descrizione. Sovrascrivendo toString()
, è possibile impedire la visualizzazione del nome e dei due punti. Questo produce un output più pulito, utile in alcuni casi.
Esempio di Eccezione Personalizzata
L'esempio seguente dichiara una nuova sottoclasse di Exception
e poi la utilizza per segnalare una condizione di errore in un metodo.
Sovrascrive il metodo toString()
, consentendo la visualizzazione di una descrizione dell'eccezione personalizzata:
// Questo programma crea un tipo di eccezione personalizzata.
class MiaEccezione extends Exception {
private int dettaglio;
MiaEccezione(int a) {
dettaglio = a;
}
public String toString() {
return "MiaEccezione[" + dettaglio + "]";
}
}
class DimostrazioneEccezione {
static void calcola(int a) throws MiaEccezione {
System.out.println("Chiamato calcola(" + a + ")");
if(a > 10)
throw new MiaEccezione(a);
System.out.println("Uscita normale");
}
public static void main(String[] args) {
try {
calcola(1);
calcola(20);
} catch (MiaEccezione e) {
System.out.println("Catturata " + e);
}
}
}
Questo esempio definisce una sottoclasse di Exception
chiamata MiaEccezione
. Questa sottoclasse è piuttosto semplice: ha solo un costruttore e un metodo toString()
sovrascritto che mostra il valore dell'eccezione. La classe DimostrazioneEccezione
definisce un metodo chiamato calcola()
che lancia un oggetto MiaEccezione
. L'eccezione viene lanciata quando il parametro intero di calcola()
è maggiore di 10. Il metodo main()
imposta un gestore di eccezioni per MiaEccezione
, poi chiama calcola()
con un valore valido (minore di 10) e uno non valido per mostrare entrambi i percorsi attraverso il codice. Ecco il risultato:
Chiamato calcola(1)
Uscita normale
Chiamato calcola(20)
Catturata MiaEccezione[20]