Capitolo 10 Eccezioni Lucidi relativi al volume: Java – Guida alla programmazione James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Eccezione Evento anormale programma che avviene durante l'esecuzione del Esempi Manipolare file non esistenti FileReader in = new FileReader("mumbers.txt“); Indice dell'array non corretto int[] a = new int[3]; a[4] = 1000; Operazioni aritmetiche improprie a[2] = 1000 / 0; Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Trattamento di un'eccezione in Java Se avviene l'eccezione ed è attivo un gestore Il flusso di controllo viene trasferito al gestore Dopo che il gestore ha completato il flusso del controllo continua con l'istruzione che segue il gestore Se avviene un'eccezione e non esiste un gestore per essa Il programma termina Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività Richiedere ed estrarre il nome di un file Da quel file, devono essere estratti due valori interi Calcolare e visualizzare il quoziente dei valori Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Implementazione Necessario perché main() non gestisce le sue possibili IOExceptions public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Filename: "); String s = stdin.readLine(); BufferedReader filein = new BufferedReader( new FileReader(s)); int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Che cosa non va? public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Filename: "); String s = stdin.readLine(); BufferedReader filein = new BufferedReader( new FileReader(s)); int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Come si possono gestire i problemi? public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Filename: "); String s = stdin.readLine(); BufferedReader filein = new BufferedReader( new FileReader(s)); int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Gestori delle eccezioni Il codice che potrebbe generare un'eccezione è inserito in un blocco try Se non vi sono eccezioni, i gestori vengono ignorati Per ogni tipo di eccezione potenziale esiste un gestore catch Al termine del gestore il programma continua con l'istruzione dopo i gestori try { Codice che potrebbe generare eccezioni di tipo E o F } catch (E e) { Gestisce l'eccezione e } catch (F f) { Gestisce l'eccezione f } Altro codice Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Introduzione ai blocchi try-catch public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Filename: "); String s = stdin.readLine(); BufferedReader filein = new BufferedReader( new FileReader(s)); int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Acquisizione del nome file BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); System.out.print("Filename: "); String s = null; try s = stdin.readLine(); } catch (IOException e) System.err.println("Cannot read input"); System.exit(0); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Impostazione dell'elaborazione del flusso dei file Copyright © 2004 - The McGraw-Hill Companies srl BufferedReader filein = null; try filein = new BufferedReader(new FileReader(s)); } catch (FileNotFoundException e) System.err.println(s + ": cannot be opened"); System.exit(0); } Come potrebbe main() generare un'espressione che non indica che potrebbe lanciare una FileNotFoundException? Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Acquisizione dell'input try int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } catch (IOException e) System.err.println(s + ": unable to read values"); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Conversione dell'input try int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } catch (IOException e) System.err.println(s + ": unable to read values"); } catch (NumberFormatException e) if (e.getMessage().equals("null")) System.err.println(s + ": need two inputs"); } else System.err.println(s + ": invalid inputs"); } } Come potrebbe main() generare un'espressione che non indica che potrebbe lanciare una NumberFormatException? Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Eccezioni di run-time Realizzate dai designer Java Le eccezioni di run-time avvengono in un programma Il costo di implementazione dei gestori per le eccezioni di run-time di solito supera il vantaggio previsto In Java un metodo può intercettarle facoltativamente o specificare che vengono lanciate Ad ogni modo, se un programma non gestisce le sue eccezioni di run-time, viene terminato quando se ne verifica una Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Calcolo del quoziente try int a = Integer.parseInt(filein.readLine()); int b = Integer.parseInt(filein.readLine()); System.out.println( a / b ); } catch (IOException e) System.err.println(s + ": unable to read values"); } catch (NumberFormatException e) if (e.getMessage().equals("null")) System.err.println(s + ": need two inputs"); } else System.err.println(s + ": invalid inputs"); } } catch (ArithmeticException e) System.err.println(s + ": unexpected 0 input value"); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Comandi type e cat La maggior parte dei sistemi operativi fornisce un comando per elencare il contenuto dei file Windows: type Unix, Linux e OS X: cat type nomefile1 nomefile2 … nomefilen Visualizza il contenuto di nomefile1 nomefile2 … nomefilen nella finestra della console Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Metodo main() possibile per Type.java public static void main(String[] args){ for (int i = 0; i < args.length; ++i) { BufferedReader filein = new BufferedReader( new FileReader(args[i])); String s = filein.readLine(); while (s != null) { System.out.println(s); s = filein.readLine(); } filein.close(); } } Che cosa non va? Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzare un blocco finally public static void main(String[] args){ for (int i = 0; i < args.length; ++i) { BufferedReader filein = new BufferedReader( new FileReader(args[i])); String s = filein.readLine(); while (s != null) { System.out.println(s); s = filein.readLine(); } filein.close(); } } Il file dovrebbe essere chiuso al termine dell'elaborazione, indipendentemente dalla causa dell'interruzione Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzare un blocco finally try { String s = filein.readLine(); while (s != null) { System.out.println(s); s = filein.readLine(); } } catch (IOException e) { System.err.println(args[i] + ": processing error"); } Eseguito sempre dopo il completamento del suo finally { blocco try-catch try { filein.close(); } catch (IOException e) { System.err.println(args[i] + ": system error"); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Eccezioni È possibile creare tipi di eccezioni personali È possibile lanciare operazioni come garantito Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività Rappresentare il deposito e il prelievo di denaro da un conto bancario Quali comportamenti sono necessari? Costruire un nuovo conto bancario vuoto BankAccount() Costruire un nuovo conto bancario con saldo iniziale BankAccount(int n) Depositare denaro addFunds(int n) Prelevare denaro removeFunds(int n) Ottenere il saldo Int getBalance() Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo esemplificativo public static void main(String[] args) throws IOException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); BankAccount savings = new BankAccount(); System.out.print("Enter deposit: "); int deposit = Integer.parseInt(stdin.readLine()); savings.addFunds(deposit); System.out.print("Enter widthdrawal: "); int withdrawal = Integer.parseInt(stdin.readLine()); savings.removeFunds(withdrawl); System.out.println("Closing balance: " + savings.getBalance()); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Attività Rappresentare il deposito e il prelievo di denaro da un conto bancario Quali comportamenti sono necessari? Costruire un nuovo conto bancario vuoto BankAccount() Costruire un nuovo conto bancario con saldo iniziale BankAccount(int n) Depositare denaro Che cosa non va? addFunds(int n) Prelevare denaro removeFunds(int n) Ottenere il saldo int getBalance() Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Creare una NegativeAmountException // Rappresenta un evento anomalo per un conto bancario public class NegativeAmountException extends Exception { // NegativeAmountException(): crea un'eccezione con // messaggio s public NegativeAmountException(String s) { super(s); } } La classe Exception fornisce il comportamento delle eccezioni necessario La classe NegativeAmountException offre la specializzazione del tipo di eccezione necessaria Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo esemplificativo public static void main(String[] args) throws IOException, NegativeAmountException { BufferedReader stdin = new BufferedReader( new InputStreamReader(System.in)); BankAccount savings = new BankAccount(); System.out.print("Enter deposit: "); int deposit = Integer.parseInt(stdin.readLine()); savings.addFunds(deposit); System.out.print("Enter widthdrawal: "); int withdrawal = Integer.parseInt(stdin.readLine()); savings.removeFunds(withdrawl); System.out.println("Closing balance: " + savings.getBalance()); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Classe BankAccount Variabile istanza balance Costruire un nuovo conto bancario vuoto BankAccount() Costruire un nuovo conto bancario con saldo iniziale BankAccount(int n) throws NegativeAmountException Depositare denaro addFunds(int n) throws NegativeAmountException Prelevare denaro removeFunds(int n) throws NegativeAmountException Ottenere il saldo Int getBalance() Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Classe BankAccount // BankAccount(): costruttore predefinito per saldo vuoto public BankAccount() { balance = 0; } // BankAccount(): costruttore specifico per nuovo saldo n public BankAccount(int n) throws NegativeAmountException { if (n >= 0) { balance = n; } else{ throw new NegativeAmountException("Bad balance"); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Classe BankAccount // getBalance(): restituisce il saldo corrente public int getBalance() { return balance; } // addFunds(): deposita l'importo n public void addFunds(int n) throws NegativeAmountException { if (n >= 0) { balance += n; } else{ throw new NegativeAmountException("Bad deposit"); } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Classe BankAccount // removeFunds(): preleva l'importo n public void removeFunds(int n) throws NegativeAmountException { if (n < 0) { throw new NegativeAmountException("Bad withdrawal"); } else if (balance < n) { throw new NegativeAmountException("Bad balance"); } else{ balance -= n; } } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo di NegativeAmountException System.out.print("Enter deposit: "); try { int deposit = Integer.parseInt(stdin.readLine()); savings.addFunds(deposit); } catch (NegativeAmountException e) { System.err.println(“Cannot deposit negative funds“); System.exit(0); } Java – Guida alla programmazione - James Cohoon, Jack Davidson Copyright © 2004 - The McGraw-Hill Companies srl Utilizzo di NegativeAmountException System.out.print("Enter withdrawal: "); try { int withdrawal = integer.parseInt(stdin.readLine()); savings.removeFunds(withdrawl); } catch (NegativeAmountException e) { if (e.message().equals("Bad withdrawal")) System.err.println(“Cannot withdraw negative funds“); else{ System.err.println("Withdrawal cannot leave " "negative balance"); } System.exit(0); }