sistemi operativi i: windows -...
TRANSCRIPT
Gestire le eccezioni
Lezione XI
IX-B.2
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Scopo della lezione
• Studiare il meccanismo di gestione delle eccezioni
• Implementare nuove eccezioni
IX-B.3
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Tipi di errori
• Errori rilevati in fase di compilazione: errori di sintassi, ...
• Errori rilevati in fase di esecuzione:– dall’utente (errori logici)– dalla JVM (eccezioni)
IX-B.4
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eccezioni
• Si definisce eccezione un errore la cui localizzazione– nello spazio (i.e. all’interno del codice
sorgente), e/o– nel tempo (rispetto all’istante di esecuzione)
risulta a priori difficile quando non impossibile
IX-B.5
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempioimport java.io.*;import prog.io.*;class EccezioneFileErrata {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + ” righe.");
}}
IX-B.6
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempiomalchiod% javac EccezioneFileErrata.javaEccezioneFileErrata.java:8: unreported exception
java.io.FileNotFoundException; must be caught or declared to be thrownnew BufferedReader(new FileReader("elenco.txt"));
^EccezioneFileErrata.java:9: unreported exception
java.io.IOException; must be caught or declared to be thrownString line = in.readLine();
^EccezioneFileErrata.java:13: unreported exception
java.io.IOException; must be caught or declared to be thrownline = in.readLine();
^3 errors
IX-B.7
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempioimport java.io.*;import prog.io.*;class EccezioneFileErrata {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + ” righe.");
}}
Cosa succede se elenco.txt non esiste?
IX-B.8
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eccezioni
• Nel caso si verifichi una condizioneinattesa (come la mancanza del file nell’esempio precedente), una classeJava lancia un’eccezione
• Il compilatore rileva le situazioni chepotrebbero generare delle eccezioni e richiede al programmatore di trattarle in modo dedicato ed esplicito
IX-B.9
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Quindi...import java.io.*;import prog.io.*;class EccezioneFileErrata {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + " righe.");
}}
se elenco.txt non esisteviene lanciata l’eccezioneFileNotFoundException
IX-B.10
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Analogamente...
Queste istruzioni possonolanciare un’eccezioneIOException
import java.io.*;import prog.io.*;class EccezioneFileErrata {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + i + "righe.");
}}
IX-B.11
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eccezioni
• La filosofia di base di Java prevede cheun codice mal progettato non verrà maieseguito
• Ogni volta che del codice potrebbelanciare delle eccezioni, alternativamente– deve essere scritto del codice aggiuntivo per
gestire le condizioni eccezionali– deve essere esplicitamente dichiarata la
possibilità di emissione di un’eccezione
IX-B.12
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Dichiarare le eccezioni
• Quando un metodo contiene codice chepotrebbe lanciare delle eccezioni, la relativa intestazione viene modificataindicando quante e quali sono questeeccezioni
• La parola chiave throws, inserita dopol’elenco dei parametri formali nelladichiarazione di un metodo, dichiara qualieccezioni possono essere lanciate
IX-B.13
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Dichiarare le eccezioniimport java.io.*; import prog.io.*;class EccezioneFile {public static void main(String[] args)
throws FileNotFoundException, IOException {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new
FileReader("elenco.txt"));String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + ” righe.");
}}
IX-B.14
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Dichiarare le eccezionimalchiod% cat elenco.txtriga 1riga 2riga 3riga 4riga 5riga 6malchiod% java EccezioneFileIl file e' lungo 6 righe.malchiod% rm elenco.txtmalchiod% java EccezioneFileException in thread "main” java.io.FileNotFoundException: elenco.txt (No such file or directory)at java.io.FileInputStream.open(Native Method)at java.io.FileInputStream.<init>(FileInputStream.java:103)at java.io.FileInputStream.<init>(FileInputStream.java:66)at java.io.FileReader.<init>(FileReader.java:41)at EccezioneFile.main(EccezioneFile.java:7)
IX-B.15
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Risolvere le eccezioni
• In un generico linguaggio diprogrammazione gli approcci allarisoluzione delle eccezioni sonoprincipalmente due– il programmatore deve verificare che prima
di eseguire un’istruzione questa non dialuogo ad un’eccezione
– il programmatore deve occuparsi di gestire le eccezioni solo dopo che queste sono state lanciate
IX-B.16
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Verifica delle eccezioniimport java.io.*;import prog.io.*;class EccezioneFileErrata {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + ” righe.");
}}
Nel primo approccio, prima di eseguire ognuna diqueste istruzioni devo verificarne la validità
IX-B.17
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestire le eccezioni
Java adotta la seconda soluzione, in quanto– permette spesso di scrivere un unico blocco
di codice che gestisca eccezioni che sipossono presentare in parti diverse del codice
– lascia che il programmatore possa separarel’implementazione del codice che gestisce le situazioni tipiche da quello che gestisce le situazioni eccezionali
IX-B.18
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestire le eccezioni
La gestione delle eccezioni avviene– dichiarando all’interno di un metodo unasezione critica di codice che potrebbelanciare una o più eccezioni
– facendo seguire questa sezione da uno o piùblocchi di codice deputati a gestire le eccezioni che possono essere lanciate
IX-B.19
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestire le eccezioni
• Una sezione critica viene indicataracchiudendo il codice relativo in unacoppia di parentesi graffe precedute dallaparola chiave try
• La parte di codice che gestisceun’eccezione segue questo blocco, racchiusa tra partentesi graffe e preceduta dalla parola chiave catch chespecifica anche l’eccezione gestita
IX-B.20
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestione delle eccezioni
Gestione dell’eccezionedi tipo Exception_2
try {
} catch(Exception_1 e) {
}catch(Exception_2 e) {
}
• Se durantel’esecuzione dellasezione critica non vengono lanciateeccezioni, l’esecuzione procedein modo regolare e i blocchi individuati dacatch vengonoignorati
Sezione critica
Gestione dell’eccezionedi tipo Exception_1
IX-B.21
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestione delle eccezioni• Se viene lanciata
un’eccezione di tipoException_1– viene interrotta
l’esecuzione dellasezione critica
– viene eseguito ilblocco catch corripondente
– viene ignorato ilrimanente bloccocatch
try {
} catch(Exception_1 e) {
}catch(Exception_2 e) {
}
Sezione critica
Gestione dell’eccezionedi tipo Exception_1
Gestione dell’eccezionedi tipo Exception_2
Exception_1
IX-B.22
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gestione delle eccezioni• Se viene lanciata
un’eccezione di tipoException_2– viene interrotta
l’esecuzione dellasezione critica
– viene ignorato il primo blocco catch
– viene eseguito ilblocco catch corripondente a Exception_2
try {
} catch(Exception_1 e) {
}catch(Exception_2 e) {
}
Sezione critica
Gestione dell’eccezionedi tipo Exception_1
Gestione dell’eccezionedi tipo Exception_2
Exception_2
IX-B.23
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eccezioni vs. switch
• La valutazione delle clausole catch nellagestione delle eccezioni ricorda ilcostrutto switch
• Viene eseguita solo la porzione di codicecorrispondente all’eccezione lanciata, MA
• Non sono previste istruzioni speciali(come break) per chiudere i singoliblocchi catch
IX-B.24
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempioimport java.io.*;import prog.io.*;
class EccezioneGestita {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();try {BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}
IX-B.25
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempio
video.println("Il file e' lungo " + (i-1) + " righe.");}catch(FileNotFoundException e) {video.println("Il file elenco.txt non esiste");}catch(IOException e) {video.println("Si e' verificata un'eccezione di IO");}
}}
IX-B.26
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempiomalchiod% java EccezioneGestitaIl file e' lungo 6 righe.
malchiod% rm elenco.txtmalchiod% java EccezioneGestitaIl file elenco.txt non esiste
malchiod%
IX-B.27
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
throw vs catch
• Le parole chiave throw e catch sonocomplementari– un codice che utilizza throw gestisce le
eccezioni che vengono lanciate all’internodei suoi metodi lanciandole a sua volta al codice che lo ha chiamato
– un codice che utilizza catch cattura le eccezioni che vengono lanciate all’internodei suoi metodi
IX-B.28
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eliminando un’eccezioneimport java.io.*;import prog.io.*;
class EccezioneMultipla {public static void main(String[] args) {
ConsoleOutputManager video=new ConsoleOutputManager();
try {BufferedReader in =
new BufferedReader(new FileReader("elenco.txt"));String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}video.println("Il file e' lungo " + (i-1) + " righe.");
}catch(IOException e) {video.println("Si e' verificata un'eccezione di IO");}
}}
IX-B.29
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Eliminando un’eccezionemalchiod% javac EccezioneMultipla.javamalchiod% java EccezioneMultipla
Si e' verificata un'eccezione di IOmalchiod%
• il programma viene compilato ugualmente......perché?
IX-B.30
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gerarchia di eccezioni
• In Java le eccezioni che vengono lanciatequando si verifica un errore sono ancheesse istanze di una classe.
• Tutte le classi che si riferiscono ad eccezioni sono sottoclassi della classeException
• Ereditare un’eccezione da un’altraeccezione permette di costruire unagerarchia di eccezioni
IX-B.31
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
La classe Exception
• L’informazione più importante di unaclasse derivata da Exception è tipicamente contenuta nel suo nome
• La classe Exception e le sue derivate non implementano metodi particolari– toString() descrive l’eccezione– printStackTrace() stampa l’eccezione e
la sequenza delle chiamate dei metodi chehanno portato a generarla
IX-B.32
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempio
Exception IOException FileNotFoundException
• Siccome FileNotFoundException è interpretabile anche come IOException, la clausola catch del codice precedente la intercetta.
IX-B.33
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Gerarchia delle eccezionitry {}catch(IOException e) {video.println("Si e' verificata un'eccezione di IO");}catch(FileNotFoundException e) {video.println("Il file elenco.txt non esiste");}
• FileNotFoundException verrebbesempre gestita dalla prima clausolacatch e la seconda sarebbe inutile
• Il compilatore riconosce questa situazioneed emette un errore
IX-B.34
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempioimport java.io.*;import prog.io.*;
class EccezioneDoppia {public static void main(String[] args) {ConsoleOutputManager video=new ConsoleOutputManager();try {BufferedReader in =new BufferedReader(new FileReader("elenco.txt"));
String line = in.readLine(); int i=1;while(line!=null) {i++;line = in.readLine();}
IX-B.35
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempio
video.println("Il file e' lungo " + (i-1) + " righe.");}catch(IOException e) {video.println("Si e' verificata un'eccezione di IO");}catch(FileNotFoundException e) {video.println("Il file elenco.txt non esiste");}
}}
IX-B.36
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Esempiomalchiod% javac EccezioneDoppia.javaEccezioneDoppia.java:21: exception
java.io.FileNotFoundException has already been caughtcatch(FileNotFoundException e) {^
1 errormalchiod%
IX-B.37
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Costruire nuove eccezioni• Estendendo la classe Exception o una
delle classi derivate da essa è possibilecostruire nuove eccezioni
• All’interno del codice è possibile lanciareeccezioni (esistenti o create appositamente) tramite il comandothrow
IX-B.38
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
MyException.javaclass MyException extends Exception {public MyException() {
}}
IX-B.39
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
TestMyException.javaimport prog.io.*;
class TestMyException {public static void main(String args[]) {ConsoleOutputManager video=new ConsoleOutputManager();
try {MyException m = new MyException();throw m;
} catch(MyException e) {video.println(e.toString());e.printStackTrace();
}}}
IX-B.40
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
TestMyExceptionmalchiod% java TestMyExceptionMyException
MyExceptionat TestMyException.main(TestMyException.java:7)
malchiod%
IX-B.41
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
TestStack.javaclass TestStack {public static void f() throws MyException {
throw new MyException(); }public static void g() throws MyException {
f();throw new MyException();
}
IX-B.42
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
TestStack.java
public static void main(String args[]) {try {f();} catch(MyException e) {e.printStackTrace();}try {g();} catch(MyException e) {e.printStackTrace();}
}}
IX-B.43
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
TestStackmalchiod% java TestStackMyException
at TestStack.f(TestStack.java:3)at TestStack.main(TestStack.java:11)
MyException
at TestStack.f(TestStack.java:3)at TestStack.g(TestStack.java:6)at TestStack.main(TestStack.java:16)
malchiod%
IX-B.44
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Runtime.javaclass Runtime {public static void main(String[] args) {
int i, j;j=0;i=3/j;
}}
IX-B.45
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Runtime.javamalchiod% javac Runtime.javamalchiod% java Runtime
Exception in thread "main" java.lang.ArithmeticException: / by zero
at Runtime.main(Runtime.java:5)
malchiod%
• Perché la compilazione va a buon fine quando main non dichiara la possibilità dilanciare ArithmeticException?
IX-B.46
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
RuntimeException
• Eccezioni come NullPointerException, ArithmeticException e ArrayIndexOutOfBoundsException, che riguardano tipicamente errori diprogrammazione, sono raggruppate nellasuperclasse RuntimeException chenon deve essere dichiarata dalprogrammatore
IX-B.47
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Finallyclass Switch {boolean state = false;
void on() {state = true; } void off() {state = false; }}
class OnOffException1 extends Exception {}class OnOffException2 extends Exception {}
IX-B.48
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Finallyclass TestSwitch {
static Switch sw = new Switch();static void f() throws OnOffException1,OnOffException2{}
public static void main(String[] args) {try {sw.on();
// Codice che può generare eccezioni...f();
sw.off();} catch(OnOffException1 e) {sw.off(); // altro codice...
} catch(OnOffException2 e) {sw.off(); // altro codice...
}}
}
Se si verificano questeeccezioni l’interruttoreviene spento
Cosa succede se si verifica un altro tipo dieccezione?
IX-B.49
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Finally
• In casi come questo risulta utile potereseguire del codice indipendentementedalla generazione di una qualsiasieccezione nel blocco try
• Questo è possibile accodando ai variblocchi catch un blocco finally
IX-B.50
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
Finallyclass TestSwitch {static Switch sw = new Switch();static void f() throws OnOffException1,OnOffException2{}public static void main(String[] args) {try {sw.on();// Codice che può generare eccezioni...f();
} catch(OnOffException1 e) {// altro codice...
} catch(OnOffException2 e) {// altro codice...
} finally {sw.off();
}}}
IX-B.51
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
LetturaFile.javaimport prog.io.*;import java.io.*;
class LetturaFile {public static void main(String[] args) {
ConsoleOutputManager out = new ConsoleOutputManager();int bytes = 0;
IX-B.52
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
LetturaFile.javatry {DataInputStream in = new DataInputStream(newFileInputStream("elenco.txt"));while(true) {in.readByte();bytes++;}} catch(EOFException e) {out.println("Il file e' lungo " + bytes + " byte");} catch(FileNotFoundException e) {out.println("Il file elenco.txt non esiste");} catch(IOException e) {out.println("Si e' verificata un’eccezione di I/O");}
}}
IX-B.53
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
LetturaDati.javaimport prog.io.*;
class EndOfDataException extends Exception {public EndOfDataException() {}
}
class LetturaDati {
public static void main(String[] args) {ConsoleOutputManager out = new ConsoleOutputManager();ConsoleInputManager in = new ConsoleInputManager();
int somma = 0,dato;
IX-B.54
Labo
rato
rio d
i Inf
orm
atic
a G
ener
ale
LetturaDati.javatry {
while(true) {out.println("Inserisci un intero (0 per uscire)");dato = in.readInt();if(dato != 0)somma += dato;elsethrow new EndOfDataException();
}} catch(EndOfDataException e) {out.println("Fine immisione dati");out.println("La somma dei numeri immessi e' " + somma);}
}}