![]() ![]() |
|
![]() ![]() |
Java fornisce una ricca gerarchia di classi di
eccezioni:
Abbiamo visto che:
Ad esempio, se in un ciclo che legge dati da internet cade la connessione, è naturale gestire questa situazione da programma senza causarne necessariamente la terminazione. |
![]() ![]() |
|
![]() ![]() |
Se una chiamata di metodo può generare
un'eccezione, possiamo racchiuderla in un blocco
try,
seguito da uno o più blocchi catch
contenenti le istruzioni da eseguire in corrispondenza dell'eccezione lanciata.
Esempio: Stampa di un array usando eccezioni (CatchOutOfBounds):
Attenzione: è questo è un PESSIMO stile di programmazione!!! |
![]() ![]() |
|
![]() ![]() |
try { <istruzioni-try>; // possono lanciare delle eccezioni } catch(<sottoclasse-Throwable1> e1) { // catturiamo l'eccezione e1 di tipo <sottoclasse-Throwable1> <istruzioni-catch1>; // gestiamo e1 } catch(<sottoclasse-Throwable2> e2) { // catturiamo l'eccezione e2 di tipo <sottoclasse-Throwable2> <istruzioni-catch2>; // gestiamo e2 } ... catch(<sottoclasse-ThrowableN> eN) { // catturiamo l'eccezione eN di tipo <sottoclasse-ThrowableN> <istruzioni-catchN>; // gestiamo e2 } finally { // istruzioni da eseguire comunque <istruzioni-finally>; } |
Se è presente almeno un blocco catch, allora il blocco finally è facoltativo.
![]() ![]() |
|
![]() ![]() |
|
![]() ![]() |
|
![]() ![]() |
Il programma seguente chiede una sequenza di interi (terminata da 0)
stampandone il quadrato:
Per evitarlo, possiamo racchiudere il comando di input in un blocco try-catch:
Per ignorare l'input errato e continuare l'esecuzione, dobbiamo mettere il try-catch all'interno del ciclo, nel modo seguente:
Ora il ciclo continua anche in presenza di input errato:
|
![]() ![]() |
|
![]() ![]() |
Le eccezioni si dividono in due categorie:
Ogni volta che scriviamo un'istruzione che potrebbe lanciare un'eccezione controllata, allora
|
![]() ![]() |
|
![]() ![]() |
La clausola throws viene inserita
nella dichiarazione del metodo per informare il compilatore che
durante l'esecuzione di quel metodo possono essere generate eccezioni
(controllate) dei tipi elencati dopo la parola chiave throws, la cui gestione viene
delegata al chiamante.
Importante: La clausola throws è sintatticamente simile ma ha un significato diverso dal comando throw !!!
Cattivo esempio:
Per evitare di dover gestire le eccezioni potremmo scrivere
tutti i metodi così:
O magari fingere di gestire ogni genere di eccezione in modo che il compilatore non segnali errori:
Così si perde molta informazione sul programma. Ignorare un problema non porta mai alla sua soluzione!
|
![]() ![]() |
|
![]() ![]() |
Perché?
Riassumendo:
|
![]() ![]() |
|
![]() ![]() |
Un esempio: IllegalTimeException
Supponiamo di avere definito la classe
Time contenente il costruttore di default, il metodo
toString(), ed il metodo
setTime() per
impostare un orario ammissibile. Come succede spesso nella
progettazione di classi di questo tipo, dobbiamo decidere come gestire il passaggio
di valori errati al metodo setTime().
Una soluzione semplice è la seguente:
Una alternantiva ragionevole in questa situazione è
quella di lanciare un'opportuna eccezione se il valore dei parametri
è errato, ad esempio una IllegalArgumentException: dopotutto
è dovere di chi invoca il metodo passare valori corretti.
Per indicare in maniera più precisa la natura dell'errore possiamo definire
una nuova classe di eccezioni IllegalTimeException:
Adesso possiamo estendere la classe Time con la classe RobustTime, sovrascrivendo opportunamente il metodo setTime().
Infine possiamo testare la classe col seguente programma TestTime :
Problema: Cosa succederebbe se la classe IllegalTimeException estendesse Exception invece di RuntimeException? Quali modifiche bisognerebbe apportare alle classi Time, RobustTime e TestTime affinché tutto funzionasse come prima? |