1. Eccezioni
>
Alla fine, i programmatori hanno pensato di standardizzare e automatizzare la gestione degli errori. Questo è successo quando sono state inventate le eccezioni . Ora il meccanismo delle eccezioni gestisce l'80% delle situazioni eccezionali.
Se qualche studioso ha fatto delle eccezioni, è probabile che fosse l'argomento della sua tesi di dottorato. Se l'ha inventato un programmatore, potrebbe aver ricevuto un'amichevole pacca sulla spalla da un collega: "Sembra a posto, fratello".
Quando si verifica un errore in un programma Java, come la divisione per 0
, accadono cose meravigliose:
Primo passo
Viene creato un oggetto eccezione speciale, che contiene informazioni sull'errore che si è verificato.
Tutto in Java è un oggetto e le eccezioni non sono eccezioni 🙂 Gli oggetti eccezione hanno le proprie classi e l'unica cosa che li distingue dalle classi ordinarie è che ereditano la Throwable
classe.
Passo due
L'oggetto eccezione è "lanciato". Forse la formulazione qui potrebbe essere migliore. "Lanciare un'eccezione" è più come attivare un allarme antincendio o emettere un avviso "DEFCON 1".
Quando viene lanciata un'eccezione alla macchina Java, il normale funzionamento del programma si interrompe e iniziano i "protocolli di emergenza".
Fase tre
Il metodo in cui è stata generata l'eccezione esce immediatamente. L'eccezione viene passata al metodo chiamante, che termina anch'esso immediatamente. E così via lungo la catena finché il main
metodo non esce. Quando il main
metodo termina, termina anche il programma.
Esempio:
Codice | Uscita console |
---|---|
|
|
Un'eccezione si verifica alla riga 20: divisione per 0. La macchina Java crea immediatamente un'eccezione — un ArithmeticException
oggetto e lo "lancia" al metodo.
Il divide()
metodo termina immediatamente, quindi non vediamo mai la stringa: Non è successo niente di terribile: 0. Il programma ritorna al endTheWorld()
metodo e la situazione si ripete: c'è un'eccezione non gestita nel sistema, il che significa che endTheWorld()
anche il metodo termina in modo anomalo. Quindi il main
metodo termina e il programma si arresta.
Qual è lo scopo di queste eccezioni? Bene, puoi scrivere il tuo codice per catturare particolari tipi di eccezioni e scrivere la tua logica per gestire situazioni eccezionali.
2. Eccezioni alla cattura:try-catch
Java ha un meccanismo di cattura delle eccezioni che ti consente di fermare questa terminazione anomala dei metodi. Sembra così:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Questo costrutto è chiamato try-catch
blocco.
Il codice in cui possono verificarsi eccezioni è racchiuso tra parentesi graffe, preceduto dalla parola try
.
Dopo le parentesi graffe abbiamo la catch
parola chiave e, tra parentesi, la dichiarazione di una variabile di eccezione . Questo è seguito da parentesi graffe che racchiudono il codice da eseguire se si verifica un'eccezione del tipo specificato .
Se non vengono lanciate eccezioni durante l'esecuzione del " codice primario ", il codice all'interno del blocco catch non verrà eseguito. Se si verifica un'eccezione, lo sarà (se il tipo dell'eccezione generata è uguale al tipo della variabile tra parentesi).
Esempio:
Codice | Uscita console |
---|---|
|
|
3. Più catch
blocchi
In teoria, tutti i tipi di eccezioni possono essere lanciati in un blocco di codice. Alcuni vorrai gestirli in un modo, altri in un altro, e altri ancora deciderai di non gestirli affatto.
Gli sviluppatori Java hanno deciso di aiutarti e di lasciarti scrivere non uno ma molti catch
blocchi dopo il try
blocco.
try
{
// Code where an exception might occur
}
catch (ExceptionType1 name1)
{
// Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
// Code for handling ExceptionType2
}
catch (ExceptionType3 name3)
{
// Code for handling ExceptionType3
}
Esempio:
Codice | Uscita console |
---|---|
|
|
4. Ordine dei catch
blocchi
Le eccezioni che si verificano in un try
blocco possono essere rilevate solo da un singolo catch
blocco. Non è possibile avere una situazione di gestione delle eccezionicatch
in cui viene eseguito il codice di più blocchi.
Ma l'ordine dei blocchi è importante.
Puoi avere una situazione in cui un'eccezione potrebbe essere rilevata da più blocchi. In tal caso, l'eccezione verrà rilevata dal blocco catch che viene prima (il più vicino al try
blocco).
Come puoi avere una situazione in cui più blocchi catch possono catturare la stessa eccezione?
Tutte le eccezioni appartengono a un'unica gerarchia di ereditarietà: vedere il diagramma.
Un ArithmeticException
oggetto può essere assegnato a una variabile il cui tipo è ArithmeticException
o una qualsiasi delle sue classi antenate: RuntimeException
, Exception
e Throwable
— vedi il diagramma.
Parleremo di più sull'ereditarietà e sulle classi ancestrali nel Livello 21.
Questo codice verrà compilato correttamente:
Vantaggi dell'eredità: |
---|
|
Quindi puoi prendere un ArithmeticException
con uno qualsiasi dei 4 catch
blocchi sopra.
Esempio 1:
Codice | Uscita console |
---|---|
|
|
In questo esempio, il ArithmeticException
può essere catturato da entrambi i blocchi catch (Exception e)
e catch (ArithmeticException e)
. Sarà catturato dal blocco più vicino al try
blocco, il primo catch
blocco.
Per evitare sorprese, è meglio posizionare catch
i blocchi in grado di rilevare quasi tutte le eccezioni vicino alla fine dell'elenco dei catch
blocchi.
Il Throwable
tipo è generalmente in grado di rilevare ogni possibile eccezione in Java . Se lo metti nel primo catch
blocco, il codice non verrà compilato, poiché il compilatore sa che ci sono blocchi di codice irraggiungibili.