Università degli Studi di Roma “Tor Vergata” Facoltà di Ingegneria Corso di Laurea in Ingegneria Informatica A. Acc. 2005/2006 Programmazione Orientata agli Oggetti OOP: L13: Eccezioni e loro trattamento in Java URM2 – ING- POC0506 G. Cantone e A. Lomartire 1 Gestione di situazioni indesiderate Data una o più istruzioni la cui esecuzione possa produrre risultati indesiderati, questi possono essere individuati e gestiti come segue: – Prevedere e testare ogni possibile situazione prevedibilmente non gradita (if) e trasferire informazioni su loro occorrenze attraverso apposite variabili, e.g. argomenti. – Modellare e trattare le occorrenze di tali eventi sincroni tramite Eccezioni, con conseguente abbandono del flusso normale di esecuzione. URM2 – ING- POC0506 G. Cantone e A. Lomartire 2 Eccezioni Sono costrutti e meccanismi che consentono di gestire situazioni particolari, poste in essere dall’esecuzione delle istruzioni costituenti l’applicazione (si tratta dunque di occorrenze interne e sincrone). L’occorrenza di un’eccezione comporta l’abbandono del normale flusso di calcolo e l’attivazione del codice apposito per quella situazione (Exception handler). A seconda dei modelli, al termine del trattamento dell’eccezione, il controllo ritorna all’istruzione che ha provocato l’eccezione (Resumptive model) oppure no (Termination model), il controllo riprendendo secondo quanto specificato nel codice dello handler. Java implementa quest’ultimo modello. URM2 – ING- POC0506 G. Cantone e A. Lomartire 3 Eccezioni Per una buona programmazione, le eccezioni dovrebbero essere impiegate solo per trattare situazioni anomale (o ritenute tali dal progettista) e non anche per gestire situazioni ordinarie. Ogni istruzione può, in teoria, provocare uno stato indesiderato. È responsabilità del progettista/ programmatore individuare, fra le istruzioni e blocchi del suo programma, quelle più esposte. URM2 – ING- POC0506 G. Cantone e A. Lomartire 4 Tipi di anomalie in Java La classe Throwable si specializza in Error, per la eventuale gestione di anomalie a livello di sistema, ed Exception per la gestione di anomalie a livello di normale codice applicativo. Una eccezione è una classe concreta non finale e come tale ha attributi e metodi. Throwable possiede il metodo getMessage() che restituisce il messaggio associato all’evento. Throwable Error Exception URM2 – ING- POC0506 G. Cantone e A. Lomartire 5 Error Java Error LinkageError •IncompatibleClassChangeError •InstantiationError VirtualMachineError •InternalError •OutOfMemoryError •StackOverflowError URM2 – ING- POC0506 G. Cantone e A. Lomartire 6 Eccezioni per tentativi di accesso illegale in Java IllegalAccessException •IllegalAccessException URM2 – ING- POC0506 G. Cantone e A. Lomartire 7 Exception Java Exception IOException RunTimeException IllegalAccessException NullPointerException URM2 – ING- POC0506 G. Cantone e A. Lomartire 8 Eccezioni IO in Java IOException •EOFException •FileNotFoundException •InterruptedIOException •MalformedURLException URM2 – ING- POC0506 G. Cantone e A. Lomartire 9 Eccezioni a tempo di esecuzione in Java RunTimeException •ArithmeticException •ClassCastException •EmptyStackException •IndexOutOfBoundException •ArrayIndexOutOfBoundException •StringIndexOutOfBoundException •NagativeArraySizeException •NullPointerException URM2 – ING- POC0506 G. Cantone e A. Lomartire 10 Esempio Serve in un metodo scrivere quanto segue? //… if (t==null) throw new NullPointerException (“t=null”) else { t.f(); //… } //… No. Ci pensa RunTimeException a sollevare l’evento nel modo anzidetto. URM2 – ING- POC0506 G. Cantone e A. Lomartire 11 Argomenti delle Eccezioni Java Dall’esempio precedente si evince che le eccezioni possono avere argomenti. URM2 – ING- POC0506 G. Cantone e A. Lomartire 12 Intercettazione di eccezioni Java Un blocco critico viene inserito in un blocco try. Questo prevede la esecuzione del codice del blocco try in modo tradizionale Se si raggiungono situazioni anomale tutto procede normalmente. URM2 – ING- POC0506 G. Cantone e A. Lomartire 13 Trattamento di eccezioni Java Un blocco try può essere seguito da una sequenza di costrutti catch (Exception handler). Se e solo se l’esecuzione del blocco try porta a una situazione anomala si abbandona il flusso normale e si entra nel catch corrispondente all’anomalia: si entra nel primo gestore utile nella sequenza. Se la eventuale sequenza di catch è chiusa da un costrutto finally, questo viene sempre eseguito, sia se trattasi di flusso normale, sia di flusso d’eccezione. Se il blocco attivato solleva un’eccezione, la precedente può essere perduta. URM2 – ING- POC0506 G. Cantone e A. Lomartire 14 Eccezioni in Java try { //…… } catch (DetailedException e1) { //… } //… catch (Exception e2) { … } finally { … } URM2 – ING- POC0506 G. Cantone e A. Lomartire Viene eseguito il blocco try e, se tutto ha successo, si salta al blocco finally, se presente, e si esce dal blocco try. Se invece una operazione solleva una eccezione, allora si salta al 1o dei blocchi catch corrispondenti. Comunque, si esegue il blocco finally 15 Eccezioni: esempio 2 public static void main (String args [ ]) { int numBiglie=1 if (args.length >0) { numBiglie= numBiglie + try { Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.out.println(“Parametro errato”); System.exit; } } .. } URM2 – ING- POC0506 G. Cantone e A. Lomartire 16 Eccezioni: esempio 3 …. try { File file1 =new File(nomeFile); } catch (FileOpenFailed ex) { System.error.println( “Impossibile aprire file: ” + nomeFile); } URM2 – ING- POC0506 G. Cantone e A. Lomartire 17 Eccezioni: esempio 4 …. try { File file1 =new File(nomeFile); processFile(file1); file1.close(); } catch (FileNotFoundException e) { System.error.println(“File non trovato: ”+ nomeFile); } } catch (FileOpenFailed ex) { System.error.println(“Impossibile aprire file: ”+ nomeFile); } URM2 – ING- POC0506 G. Cantone e A. Lomartire 18 Eccezioni: multiple anomalie …. try { File file1 =new File(nomeFile); processFile(file1); file1.close(); } catch (FileNotFoundException e) { System.error.println(“File non trovato: ”+ e); e.stackTrace(); } } catch (FileOpenFailed ex) { System.error.println(“Impossibile aprire file: ”+ e); e.stackTrace(); } } URM2 – ING- POC0506 G. Cantone e A. Lomartire 19 Rilancio delle eccezioni • È possibile, all’interno di un metodo, non gestire tutte le eccezioni che vi si possono sollevare, o gestire un’eccezione solo in parte , e “passare la palla” al chiamante. Ciò è dichiarato esplicitamente attraverso l’impiego di throws <nome eccezione> nella dichiarazione del metodo. URM2 – ING- POC0506 G. Cantone e A. Lomartire 20 Rilancio eccezioni: esempio class TalDeiTali { public …nomeMetodo(…) throws IOException, AltraEcc { … trow new IOException(…); … … trow new AltraEcc (…); … } URM2 – ING- POC0506 G. Cantone e A. Lomartire 21 Eccezioni d’utente Le eccezioni possono essere codificate impiegando tutto quanto già detto a riguardo dell’ereditarietà. Esse possono essere istanziate e lanciate esplicitamente all’interno del codice utente tramite la parola chiave throw throw new EccezioneUtente(); URM2 – ING- POC0506 G. Cantone e A. Lomartire 22 Esempio definizione e impiego di variazione di eccezione class Stack { private int indice; private Vector valori; … Object pop() throws Exception { if (indice <0) throw new Exception (“Tentativo di prelievo da stack vuoto\n”); Object risultato = valori.elementAt(indice); indice--; return risultato; } URM2 – ING- POC0506 G. Cantone e A. Lomartire 23 Esempio di estensioni di eccezione class StackUnderFlowException extends Exception { StackUnderFlowException () {super();} StackUnderFlowException (String frase) {super(frase);} } URM2 – ING- POC0506 G. Cantone e A. Lomartire 24 Esempio d’uso di eccezioni estese class Stack { private int indice; private Vector valori; … Object pop() throws StackUnderFlowException { if (indice <0) throw new StackUnderFlowException (); Object risultato = valori.elementAt(indice); indice--; return risultato; } URM2 – ING- POC0506 G. Cantone e A. Lomartire 25 Definizione di nuove eccezioni Bisogna ereditare da una classe di eccezione già definita, al limite Exception. URM2 – ING- POC0506 G. Cantone e A. Lomartire 26 Esempio def. e uso nuova eccezione class SempliceEccezione extends Exception{} public class DemoSempliceEccezione { public void f() throws SempliceEccezione { System.out.println( “f() solleva SempliceEccezione”); throw new SempliceEccezione(); } Public static void main (String[] args) { DemoSempliceEccezione sed= new DemoSempliceEccezione(); try{ sed.f(); } catch (SempliceEccezione e) { System.out.println(“Presa eccezione!”); } URM2 – ING- POC0506 G. Cantone e A. Lomartire 27 Esempio def. e uso nuova eccezione class EccezioneDiEckel extends Exception{ public EccezioneDiEckel () {} public EcexioneDiEckel (String msg) {super(msg);} } public class CostruttoriPieni { public static void f() throws EccezioneDiEckel { System.out.println( “g() solleva EccezioneDiEckel”); throw new EccezioneDiEckel(“Originata in g()”); } Public static void main (String[] args) { try{ f(); } catch (EccezioneDiEckel e) { e.printStackTrace(System.err); } URM2 – ING- POC0506 G. Cantone e A. Lomartire 28 Esempio def. e uso nuova eccezione (cont.) try{ g(); } catch (EccezioneDiEckel e) { e.printStackTrace(System.err); } } } URM2 – ING- POC0506 G. Cantone e A. Lomartire 29