Eccezioni Eccezioni
Corso di Programmazione Corso di Programmazione CdS:
CdS: Informatica e TecnologieInformatica e Tecnologie per la Produzione di Software per la Produzione di Software Nicola Fanizzi Nicola Fanizzi
fanizzi@di.uniba.it fanizzi@di.uniba.it
22
Eccezione Eccezione
Evento anormale che avviene durante l'esecuzione del Evento anormale che avviene durante l'esecuzione del programma
programma
EsempiEsempi
Manipolare file non esistentiManipolare file non esistenti
FileReader in = new FileReader("mumbers.txt“);
FileReader in = new FileReader("mumbers.txt“);
Indice dell'array non correttoIndice dell'array non corretto
int[] a = new int[3];
int[] a = new int[3];
a[4] = 1000;
a[4] = 1000;
Operazioni aritmetiche improprieOperazioni aritmetiche improprie
a[2] = 1000 / 0;
a[2] = 1000 / 0;
33
Eccezioni in Java Eccezioni in Java
Le eccezioni di run-time avvengono in un Le eccezioni di run-time avvengono in un programma
programma
Il costo di implementazione dei gestori per le eccezioni Il costo di implementazione dei gestori per le eccezioni di run-time di solito supera il vantaggio previsto
di run-time di solito supera il vantaggio previsto
In Java un metodo può scegliere di intercettarle In Java un metodo può scegliere di intercettarle o specificare che vengono (ri-)lanciate
o specificare che vengono (ri-)lanciate
Se un programma non gestisce le sue eccezioni di Se un programma non gestisce le sue eccezioni di run-time, termina quando se ne verifica una
run-time, termina quando se ne verifica una
44
Trattamento delle Eccezioni Trattamento delle Eccezioni
Se avviene l'eccezione ed è attivo un Se avviene l'eccezione ed è attivo un gestoregestore
Il flusso di controllo viene trasferito al gestoreIl flusso di controllo viene trasferito al gestore
Dopo che il gestore ha completato il flusso del Dopo che il gestore ha completato il flusso del
controllo continua con l'istruzione che segue il gestore controllo continua con l'istruzione che segue il gestore
Se avviene un'eccezione e non esiste un gestore Se avviene un'eccezione e non esiste un gestore per essa
per essa
Il programma termina (con errore di run-time)Il programma termina (con errore di run-time)
55
Trattamento delle Eccezioni Trattamento delle Eccezioni
utilizzo della gestione delle eccezioniutilizzo della gestione delle eccezioni
elaborare direttamente i casi eccezionalielaborare direttamente i casi eccezionali
gestione uniforme in grandi progettigestione uniforme in grandi progetti
togliere il codice di gestione degli errori dalla linea togliere il codice di gestione degli errori dalla linea principale del controllo di programma
principale del controllo di programma
un metodo intercetta un errore e lancia un metodo intercetta un errore e lancia un'eccezione
un'eccezione
errore gestito dal gestoreerrore gestito dal gestore
eccezioni non gestite possono produrre effetti negativi eccezioni non gestite possono produrre effetti negativi
terminazione prematura del programma terminazione prematura del programma
66
Esempio Esempio
Richiedere ed estrarre il nome di un fileRichiedere ed estrarre il nome di un file
Da quel file, devono essere estratti due Da quel file, devono essere estratti due valori interi
valori interi
Calcolare e visualizzare il quoziente dei Calcolare e visualizzare il quoziente dei valori
valori
77
Implementazione Implementazione
public static void public static void
main(String[] args) throws IOException main(String[] args) throws IOException {{
BufferedReader stdin = new BufferedReader(
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
new InputStreamReader(System.in));
System.out.print("Filename:
System.out.print("Filename: "); ");
String s = stdin.readLine();
String s = stdin.readLine();
BufferedReader filein = new BufferedReader(
BufferedReader filein = new BufferedReader(
new FileReader(s));
new FileReader(s));
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
Necessario perché
Necessario perché main()main() non gestisce le sue possibili non gestisce le sue possibili
IOException IOExceptionss
88
Problema:
Problema:
Gestire Casi Eccezionali Gestire Casi Eccezionali
public static void public static void
main(String[] args) throws IOException main(String[] args) throws IOException {{
BufferedReader stdin = new BufferedReader(
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
new InputStreamReader(System.in));
System.out.print("Filename:
System.out.print("Filename: "); ");
String s = stdin.readLine();
String s = stdin.readLine();
BufferedReader filein = new BufferedReader(
BufferedReader filein = new BufferedReader(
new FileReader(s));
new FileReader(s));
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
99
Gestione: Panoramica Gestione: Panoramica
il codice che potrebbe generare eccezioni va nei blocchi il codice che potrebbe generare eccezioni va nei blocchi trytry
il codice che gestisce un errore va in un blocco il codice che gestisce un errore va in un blocco catchcatch
l'eventuale blocco l'eventuale blocco finallyfinally viene sempre eseguito viene sempre eseguito
la clausola throwsla clausola throws specifica le eccezioni lanciate dal specifica le eccezioni lanciate dal metodo
metodo
l'istruzione l'istruzione throwthrow lancia un'eccezione (sincronalancia un'eccezione (sincrona))
1010
Gestori di Eccezioni Gestori di Eccezioni
Il codice che potrebbe generare un'eccezione Il codice che potrebbe generare un'eccezione è inserito in un blocco
è inserito in un blocco trytry
Se non vi sono eccezioni, i gestori vengono ignoratiSe non vi sono eccezioni, i gestori vengono ignorati
Per ogni tipo di eccezione potenziale esiste un gestore Per ogni tipo di eccezione potenziale esiste un gestore catchcatch
Al termine dell'azione del gestore, il programma continua con Al termine dell'azione del gestore, il programma continua con l'istruzione dopo i gestori
l'istruzione dopo i gestori
try {try {
Codice che potrebbe generare eccezioni di tipo E o F Codice che potrebbe generare eccezioni di tipo E o F }}
catch (E e) catch (E e) {{
Gestisce l'eccezione e Gestisce l'eccezione e }}
catch (F f) catch (F f) {{
Gestisce l'eccezione f Gestisce l'eccezione f }}
Altro codice Altro codice
1111
Blocchi
Blocchi try..catch try..catch
public static void main(String[] args) public static void main(String[] args) throws IOException
throws IOException {{
BufferedReader stdin = new BufferedReader(
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
new InputStreamReader(System.in));
System.out.print("Nome File:
System.out.print("Nome File: "); ");
String s = stdin.readLine();
String s = stdin.readLine();
BufferedReader filein = new BufferedReader(
BufferedReader filein = new BufferedReader(
new FileReader(s));
new FileReader(s));
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
1212
Acquisizione del Nome File Acquisizione del Nome File
BufferedReader stdin = new BufferedReader(
BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in));
new InputStreamReader(System.in));
System.out.print("Nome File:
System.out.print("Nome File: "); ");
String s = null;
String s = null;
try { try {
s = stdin.readLine();
s = stdin.readLine();
}}
catch (IOException e) { catch (IOException e) {
System.err.println("non posso leggere l'input");
System.err.println("non posso leggere l'input");
System.exit(0);
System.exit(0);
}}
1313
Impostazione Impostazione
BufferedReader filein = null;
BufferedReader filein = null;
try { try {
filein = new BufferedReader(new FileReader(s));
filein = new BufferedReader(new FileReader(s));
}}
catch (FileNotFoundException e) { catch (FileNotFoundException e) {
System.err.println(s + ":
System.err.println(s + ": non può essere aperto");non può essere aperto");
System.exit(0);
System.exit(0);
}}
main()
main() così non è costretto a dichiarare di così non è costretto a dichiarare di lanciare una
lanciare una FileNotFoundExceptionFileNotFoundException
1414
Acquisizione dell'Input Acquisizione dell'Input
try { try {
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
catch (IOException e) { catch (IOException e) {
System.err.println(s + ":
System.err.println(s + ": incapace di leggere valori");incapace di leggere valori");
}}
1515
Conversione dell'Input Conversione dell'Input
try try
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
catch (IOException e) catch (IOException e)
System.err.println(s + ":
System.err.println(s + ": incapace di leggere valori");incapace di leggere valori");
}}
catch (NumberFormatException e) catch (NumberFormatException e)
if (e.getMessage().equals("null")) if (e.getMessage().equals("null"))
System.err.println(s + ":
System.err.println(s + ": necessari 2 argomenti");necessari 2 argomenti");
}} elseelse
System.err.println(s + ":
System.err.println(s + ": input non valido");input non valido");
}}
}} Come potrebbe main()Come potrebbe main() generare un'espressione che non generare un'espressione che non indica che potrebbe lanciare una
indica che potrebbe lanciare una NumberFormatExceptionNumberFormatException??
1616
Gerarchia delle Eccezioni Gerarchia delle Eccezioni
Superclasse Superclasse ThrowableThrowable
Sottoclasse Sottoclasse ExceptionException
situazioni eccezionali situazioni eccezionali
dovrebbero essere gestite dal programma dovrebbero essere gestite dal programma
Sottoclasse Sottoclasse ErrorError
tipicamente non gestire dal programma tipicamente non gestire dal programma
eccezioni controllate (eccezioni controllate (checkedchecked))
il compilatore controlla se il metodo gestisce o dichiara di il compilatore controlla se il metodo gestisce o dichiara di lanciare un'eccezione
lanciare un'eccezione
eccezioni non controllate (eccezioni non controllate (uncheckedunchecked))
errori standard di runtimeerrori standard di runtime
1717
Gerarchia della Classe Gerarchia della Classe
Throwable Throwable
Throwable Throwable
Exception Exception
Error Error
IOException IOException RuntimeException RuntimeException
AWTError AWTError ThreadDeath ThreadDeath OutOfMemoryError OutOfMemoryError
1818
Calcolo del Quoziente Calcolo del Quoziente
try try
int a = Integer.parseInt(filein.readLine());
int a = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
int b = Integer.parseInt(filein.readLine());
System.out.println( a / b );
System.out.println( a / b );
}}
catch (IOException e) catch (IOException e)
System.err.println(s + ":
System.err.println(s + ": incapace di leggere valori");incapace di leggere valori");
}}
catch (NumberFormatException e) catch (NumberFormatException e)
if (e.getMessage().equals("null")) if (e.getMessage().equals("null"))
System.err.println(s + ":
System.err.println(s + ": necessita di 2 argomenti");necessita di 2 argomenti");
}} elseelse
System.err.println(s + ":
System.err.println(s + ": input non valido");input non valido");
}} }}
catch (ArithmeticException e) catch (ArithmeticException e)
System.err.println(s + ":
System.err.println(s + ": unexpected 0 input value");unexpected 0 input value");
}}
1919
Type.java Type.java
public static void main(String[] args) public static void main(String[] args){{
for (int i = 0; i < args.length; ++i) for (int i = 0; i < args.length; ++i) {{
BufferedReader filein = new BufferedReader(
BufferedReader filein = new BufferedReader(
new FileReader(args[i]));new FileReader(args[i]));
String s = filein.readLine();
String s = filein.readLine();
while (s != null) while (s != null) {{
System.out.println(s); System.out.println(s);
s = filein.readLine(); s = filein.readLine();
}}
filein.close();
filein.close();
}} }}
Che cosa non va?
Che cosa non va?
2020
finally finally
Resource leak/Mancanza di risorseResource leak/Mancanza di risorse
causata dal fatto che il programma potrebbe causata dal fatto che il programma potrebbe non rilasciare le risorse impegnate
non rilasciare le risorse impegnate
blocco blocco finallyfinally
compare dopo i blocchi compare dopo i blocchi catchcatch
viene sempre eseguitoviene sempre eseguito
si usa per restituire le risorse impegnatesi usa per restituire le risorse impegnate
2121
Blocco
Blocco finally finally
public static void main(String[] args) public static void main(String[] args){{
for (int i = 0; i < args.length; ++i) for (int i = 0; i < args.length; ++i) {{
BufferedReader filein = new BufferedReader(
BufferedReader filein = new BufferedReader(
new FileReader(args[i]));new FileReader(args[i]));
String s = filein.readLine();
String s = filein.readLine();
while (s != null) while (s != null) {{
System.out.println(s);System.out.println(s);
s = filein.readLine(); s = filein.readLine();
}}
filein.close();
filein.close();
}} }}
Il file dovrebbe essere chiuso al termine dell'elaborazione, Il file dovrebbe essere chiuso al termine dell'elaborazione, indipendentemente dalla causa dell'interruzione
indipendentemente dalla causa dell'interruzione
2222
Utilizzare
Utilizzare finally finally
try {try {
String s = filein.readLine();
String s = filein.readLine();
while (s != null) while (s != null) {{
System.out.println(s);
System.out.println(s);
s = filein.readLine();
s = filein.readLine();
}} }}
catch (IOException e) catch (IOException e) {{
System.err.println(args[i] + ":
System.err.println(args[i] + ": processing error");processing error");
}}
finally finally {{
try {try {
filein.close();
filein.close();
}}
catch (IOException e) catch (IOException e) {{
System.err.println(args[i] + ":
System.err.println(args[i] + ": system error");system error");
}} }}
Eseguito sempre dopo il completamento del blocco
Eseguito sempre dopo il completamento del blocco try-catchtry-catch
2323
Rilanciare un'Eccezione Rilanciare un'Eccezione
le eccezioni assenti dai blocchi le eccezioni assenti dai blocchi catchcatch vanno vanno rilanciate (clausola
rilanciate (clausola throwsthrows))
è posibile rilanciare eccezioni che sono istanze è posibile rilanciare eccezioni che sono istanze delle estensioni (sottoclassi) di quelle dichiarate delle estensioni (sottoclassi) di quelle dichiarate
dal metodo dal metodo
NON è possibile rilanciare alcun altro tipo di NON è possibile rilanciare alcun altro tipo di eccezione controllata
eccezione controllata
Le eccezioni non controllabili che sono istanze di Le eccezioni non controllabili che sono istanze di RunTimeException
RunTimeException e e ErrorError non devono non devono essere dichiarate
essere dichiarate
2424
Stack di Esecuzione Stack di Esecuzione
Eccezione non gestita nella sua zona di visibilitàEccezione non gestita nella sua zona di visibilità
il metodo terminail metodo termina
la pila viene la pila viene sgomitolatasgomitolata
altro tentativo di altro tentativo di catchcatch di un eccezione di un eccezione
ThrowableThrowable
printStackTrace()printStackTrace()
stampa lo stack di chiamate del metodo stampa lo stack di chiamate del metodo
getStackTrace() getStackTrace()
reperisce informazioni sul trace della pila reperisce informazioni sul trace della pila
getMessage()getMessage()
restituisce una stringa di descrizione restituisce una stringa di descrizione
2525
Creare Eccezioni Creare Eccezioni
È possibile creare tipi di eccezioni personali, È possibile creare tipi di eccezioni personali, estendendo le classi di quelle esistenti e
estendendo le classi di quelle esistenti e
aggiungendo alla stringa di descrizione altre aggiungendo alla stringa di descrizione altre
informazioni informazioni
public class AttributoInesistenteException { public class AttributoInesistenteException {
public String attributo;
public String attributo;
public AttributoInesistenteException(String nome) { public AttributoInesistenteException(String nome) {
super("attributo " + nome + "inesistente");
super("attributo " + nome + "inesistente");
attributo = nome;
attributo = nome;
}} }}