Gestione delle eccezioni Raffaella Brighi, a.a. 2007/08 Ereditarietà Corso di Algoritmi e programmazione. A.A. 2007-08 CdL Operatore Informatico Giuridico. Casi di insuccesso Vi sono numerosi problemi che possono portare all insuccesso nell esecuzione di un metodo: da errori dovuti ai dati in ingresso (input) ad errori di programmazione. Un programma deve essere in grado di gestire il fallimento: individuazione e ripristino. Il meccanismo di gestione delle eccezioni consente di specificare cosa deve fare il programma quando l esecuzione di un metodo fallisce. I principi sono: le eccezioni non devono poter essere trascurate le eccezioni devono essere gestire da un gestore di eccezioni.
public class ContoCorrente double saldo; public void preleva(double valore) saldo=saldo-valore;//il saldo può diventare negativo System.out.println ( inserire un numero tra 1 e10 ); num=inp.nextint() // se num>10 errore di input System.out.println ( inserire un numero ); int num=inp.nextint() // errore se l utente non inserisce un numero intero String filename= c:\pippo ; Filereader reader = new FileReader(filename);//errore se il file viene trovato Scanner in = new Scanner (reader); Segnalare eccezioni Quando il programma intercorre in una situazione di errore occorre lanciare un oggetto eccezione di tipo appropriato, vale a dire segnalare tale situazione (INDIVIDUAZIONE DELL ECCEZIONE). throw oggettoeccezione; throw lancia Nel momento in cui viene lanciata un eccezione il controllo passa al gestore delle eccezioni ed il metodo termina immediatamente.
La classe Exception Java fornisce molti classi per rappresentare situazioni di errori. Quindi per lanciare eccezioni dobbiamo creare istanze di tali classi (oggettoeccezione) e richiamare l istruzione throw. Throwable Error Exception IOException ClassNotFou ndexception Runtime Exception Arithmetic Exception IllegalArgument Exception IndexOutOfBuon d Exception public class ContoCorrente double saldo; public void preleva(double valore) if (valore >saldo) IllegalArgumentException exception = new IllegalArgumentException ( prelievo non disponibile ) throw exception; else saldo=saldo-valore; ---------------------------------------------------- System.out.println ( inserire un numero tra 1 e10 ); int num=inp.nextint() if (num<1 num >10) throw new RuntimeException( input non valido ). ---------------------------------------------------------------------- Scanner inp = new Scanner (System.in); System.out.println ( inserire un numero ); num=inp.nextint() se l utente inserisce un dato che non sia un intero il metodo nextint() della classe Scanner lancia un eccezione InputMismatchException()
Eccezioni personalizzate E possibile creare classi di eccezioni per controllare casi di insuccesso specifici estendendo la classe Exception o RuntimeException. public class InsufficientFundsException extends RuntimeException public InsufficientFundsException() public InsufficientFundsException(String message) super(message); Eccezioni controllate e non controllate Le eccezioni controllate sono eccezioni per cui il compilatore verifica che l eccezione non venga ignorata. E obbligatorio quindi gestire l eccezione. Sono controllate ad esempio tutte le eccezioni IOException. Di regola sono controllate eccezioni dovute a circostanze esterne che non dipendono dal programmatore (es errori di connessione, ecc.) Per dichiarare che un metodo deve terminare se viene lanciata al suo interno un eccezione controllata si contrassegna il metodo con l istruzione throws public void read (String filename) throws FileNotFoundException Le eccezioni non controllate possono essere ignorate (anche se non è buona norma). Sono eccezioni di tipi RuntimeException.
Catturare le eccezioni try istruzione; istruzione; catch (ClasseEccezione oggettoeccezione) istruzione; istruzione; catch (ClasseEccezione oggettoeccezione) istruzione; istruzione; Nel blocco try vengono eseguiti una o più istruzioni che generano eccezioni. Se viene lanciata un eccezione l esecuzione si interrompe e riprende nel blocco catch corrispondente. ContoCorrente cc = new ContoCorrente(100); try cc.preleva(200); catch (IllegalArgumentException exception) System.out.println(exception.getMessage()); --------------------------------- try Scanner inp = new Scanner (System.in); System.out.println ( inserire un numero ); int num=inp.nextint() catch (InuptMismatchException exception) System.out.println(exception.getMessage());
Clausola finally La clausola finally consente di specificare un blocco di istruzioni che devono essere eseguite sempre alla fine del blocco try anche se non si solleva un eccezione. Esercizio 1 Progettare la classe Intervista, che ha lo scopo di porre domande ad uno o più utenti e memorizzarne le preferenze. La classe fornisce i seguenti servizi: compilaanagrafica(): chiede il nome dell utente e l età (l età deve essere un numero positivo e minore di 100) domanda1(): sottopone all utente la seguenti domande a riposta multipla 1) leggi libri (si/no)? domanda2(): sottopone all utente la seguenti domande a riposta multipla genere preferito (gialli/romanzi/saggi) Progettare anche la classe Risposta, caratterizzata da nome, eta, leggelibri (boolean) e genere, per memorizzare le risposte di ogni singola persona intervistata. salvaintervista() memorizza una Risposta completa in una arraylist. Nota implementare una classe personalizzata BadDataException, estensione di RuntimeException per gestire eventuali errori di input Realizzare il programma client che intervista una persona: la domanda 2 viene posta solo se l utente ha risposto si alla domanda 1. Eventuali errori di input vengono indicati dal programma all utente e l intervista termina
package prginterviste; public class BadDataException extends RuntimeException public BadDataException() /** Creates a new instance of BadDataException */ public BadDataException(String message) super (message); package prginterviste; public class Risposta String nome, genere; boolean leggelibri; int eta; /** Creates a new instance of Risposta */ public Risposta (String fnome, int feta, boolean flegge, String fgenere) genere=fgenere; eta=feta; leggelibri=flegge; nome=fnome;
import java.util.scanner; import java.util.inputmismatchexception; import java.util.arraylist; public class Intervista String nome, genere; int eta; ArrayList<Risposta> risposte= new ArrayList<Risposta>(); boolean leggelibri; /** Creates a new instance of Intervista */ public Intervista() public void compilaanagrafica() throws InputMismatchException Scanner inp= new Scanner(System.in); System.out.println ("Inserisci il tuo nome"); nome= inp.nextline(); System.out.println ("Inserisci la tua età"); inp= new Scanner (System.in); int eta= inp.nextint(); if (eta<0 eta>100) throw new BadDataException ("Errore di input: dato età non valido."); public boolean domanda1() System.out.println ("Ti piace leggere? (SI/NO)"); Scanner inp= new Scanner (System.in); String risp= inp.nextline(); if (risp.equals("si")) leggelibri=true; else if (risp.equals("no")) leggelibri=false; else throw new BadDataException("Errore di input: la risposta deve essere si o no"); return leggelibri; public void domanda2() genere=""; System.out.println ("Quale è il tuo genere preferito? (a-b-c)"); Scanner inp= new Scanner (System.in); String risp= inp.nextline(); if (risp.equals("a")) genere="romanzo"; else if (risp.equals("b")) genere="giallo"; else if (risp.equals ("c")) genere = "saggio"; else throw new BadDataException("Errore di input: digitare a, b o c"); public void salvarisposta() risposte.add(new Risposta (nome, eta,leggelibri,genere));
import java.util.inputmismatchexception; public class Main public static void main(string[] args) Intervista myintervista = new Intervista (); try myintervista.compilaanagrafica(); if (myintervista.domanda1()) myintervista.domanda2(); myintervista.salvarisposta(); catch (BadDataException exception) System.out.println (exception.getmessage()); catch (InputMismatchException exception) System.out.println ("LOG: Tipo non corrispondente. Stacktrace= " + exception.getstacktrace()); // TODO code application logic here Esercizio 1 II parte Modificare il programma driver perché vengano intervistate 100 persone, anziché una. Se si verificano errori di input in una delle risposte dell utente, si passa all intervista succesiva. Alla fine dell intervista stampare tutte le riposte salvate. Migliorare l esercizio precedente passando all intervista successiva se entro 1 min l utente non inserisce l input.
Esercizio 2 Progettare in UML e implementare in java la classe ProfessoreUniversitario. Il professore è caratterizzato da nome e numero di matricola. Ogni professore segue una o più tesi. Per rappresentare le tesi definire la classe Tesi: caratterizzata dal nome del tesista, dal titolo della tesi, dal campo booleano discussa (true/false) e dai metodi: - registravoto (int voto): che memorizza il voto e imposta a true il flag di discussione della tesi. Gestire come errore il caso in cui si cerchi di registrare il voto per una tesi già discussa. - tostring(): restituisce nome del tesista, titolo della tesi ed eventualmente voto per le tesi discusse. - boolean equals (Object anobject): verifica se due oggetti Tesi sono uguali (per esserlo devono avere nometesista uguale). La classe ProfessoreUniversitario fornisce i seguenti servizi: - getdescrizione(): restituisce nome e numero di matricola del Professore - aggiungitesi(nometesista, titolo): aggiunge una Tesi all'elenco delle tesi seguite. Gestire come errore il caso in cui si cerchi di inserire una tesi ad un tesista già esistente (nota: utilizzare il metodo equals della classi Tesi). - archiviatesi(nometesista, voto): il metodo prende in input il nome del tesista e il voto e aggiorna l'oggetto Tesi corrispondete. - elencatesi(): stampa l'elenco di tutte le tesi seguite dal professore (nome tesista, titolo ed eventualmente voto) Gestire gli errori definendo classi Eccezioni personalizzate. Esercizio 2 II parte 2) Partendo dalla classe ProfessoreUniversitario progettare e implementare in java le classi: ProfessoreAssociato e ProfessoreOrdinario. Per entrambe le sottoclassi il metodo getdescrizione deve restituire anche il ruolo. Il Professore ordinario, a differenza del Professore associato, può essere coordinatore di una ricerca, per la quale viene eventualmente memorizzato il titolo. La classe ProfessoreOrdinario fornisce i metodi: - coordinaricerca (titolo): prende in input il titolo della ricerca e la assegna al professore. Gestire come errore il caso in cui il professore sia coordinatore di altre ricerche restituisce un messaggio di errore. - getricerca (): indica se il professore è coordinatore o meno di una ricerca e ne restituisce il titolo.