1 / 56

Exception Handling

Hoofdstuk 14:. Exception Handling. 1. Inleiding – soorten exceptions. Exception:

reese
Download Presentation

Exception Handling

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Hoofdstuk 14: Exception Handling JAVA -- H14

  2. 1. Inleiding – soorten exceptions • Exception: • ongewone of foutieve situatie, bv. delen door nul -> console-applicatie mislukt ; applet geeft fout in het console-venster ; GUI-applicatie kan eveneens verder gezet worden, maar ze verkeren in een onstabiele toestand-> kunnen verkeerde resultaten geven • kan onderschept en afgehandeld worden. • = een object van de klasse Throwable, gegenereerd door de programmeur of door het systeem, d.m.v. een throw-opdracht vb. throw new NumberFormatException() JAVA -- H14

  3. EXCEPTION HANDLING - SOORTEN • Error kan niet hersteld worden (interne fouten in de run-time omgeving van JVM) • Klassenhiërarchie van de belangrijkste errors en exceptions: • Throwable (= superklasse)Error (unchecked) LinkageError NoClassDefFoundError IncompatibleClassChangeError VirtualMachineError OutOfMemoryError StackOverflowError JAVA -- H14

  4. EXCEPTION HANDLING - SOORTEN Exception (allemaal checked, behalve RunTimeException) RunTimeException (unchecked) NullPointerException ArithmeticException IndexOutOfBoundsException ArrayIndexOutOfBoundsException IllegalArgumentException NumberFormatException IOException (checked) FileNotFoundException MalformedURLException InterruptedException (checked) JAVA -- H14

  5. 2. Wanneer moet exception handling gebruikt worden? • Gebruikmaken van exception handling • Wanneer een methode zijn taak niet kan voltooien. • Wanneer componenten van een programma niet in staat zijn om de exceptions die optreden onmiddellijk af te handelen. • Om exceptions op een uniforme wijze af te handelen in grote projecten. JAVA -- H14

  6. 2. Wanneer moet exception handling gebruikt worden? • Unchecked (RuntimeException, Error) • Worden niet gecontroleerd door de compiler. • Kan overal in de code voorkomen, deze altijd afhandelen is onmogelijk. • Je kan ze afhandelen als je dat wil! • Geven een fout aan in het programma. • Checked (al de andere) • Worden gecontroleerd door de compiler. • Moeten afgehandeld worden! JAVA -- H14

  7. 3. Exceptions afhandelen-OPLOSSINGEN • helemaal niets, geen speciale code in het programma -> systeemfoutboodschap (1) • afhandeling op de plaats waar de fout optreedt (duidelijk en vlugger) -> try-catch-finally-statement (2) • afhandeling op een andere plaats -> impliciete of expliciete exception propagation (3) JAVA -- H14

  8. Voorbeeld - (1) public class Zero { public static void main(String[] args) { int teller = 10, noemer = 0; System.out.println( teller / noemer); } } -> SYSTEEMFOUTBOODSCHAP: java.lang.ArithmeticException: / by zero at Zero.main (Zero.java:4) JAVA -- H14

  9. 4. Basiseigenschappen van Exception Handling in Java • alle instructies waarin zich fouten kunnen voordoen en alle instructies die niet mogen uitgevoerd worden wanneer een exception optreedt : try-block • als er een fout optreedt in het try-block, dan wordt er een instantie van een exception-class gemaakt en deze kan opgevangen worden in 0 of meerdere catch-blocks; elk verwerkt een bepaald soort fout: catch-block • code die hoe dan ook moet uitgevoerd worden (bv. vrijgeven van resources) : finally-block [optioneel] JAVA -- H14

  10. 4. Basiseigenschappen van Exception Handling in Java (2) • een throws-clausule in een methode-definitie geeft aan welke exceptions de methode gooit; deze clausule staat achter de parameterlijst en voor de body van de methode; meerdere soorten worden gescheiden door komma’s: • void f(int x) throwsIOException, NumberFormatException { // …} • dergelijke exceptions kunnen gegooid worden door statements in de methode-body of door methoden die in de body aangeroepen worden = throw punt JAVA -- H14

  11. 5. Try - blocks • Het try-catch-finally statement:try { // code dat mag falen} catch (Exception e) { // afhandelen Exception // meerdere catchers mogelijk} [finally { // code die altijd uitgevoerd //wordt}] • Let op: 1. in een catch-blok kan je geen gebruikmaken van objecten gedeclareerd in het corresponderende try-blok! 2. Tussen de catchers en het try-blok kan geen andere code staan! JAVA -- H14

  12. Voorbeeld 1 try { int a[]= new int[2]; a[5] = 1; } catch(ArrayIndexOutOfBoundsException fout) { System.out.println(“Fout:” + fout.getMessage());} JAVA -- H14

  13. Voorbeeld 2: 2 getallen inlezen, som berekenen import java.io.*; public class Som { public static void main( String[] args) { int get1 = Gebruiker_Lees.getInteger("Geef een getal: "); int get2 = Gebruiker_Lees.getInteger("Geef een 2°getal: "); System.out.println("Som = " + (get1 + get2)); } } JAVA -- H14

  14. class Gebruiker_lees { public static int getInteger(String prompt) { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); int getal = 0; boolean geldig = false; while (! geldig) { System.out.print(prompt); //geen nieuwe lijn System.out.flush(); JAVA -- H14

  15. try { getal = Integer.parseInt(stdin.readLine()); geldig = true; // uit de lus! } catch (NumberFormatException exception) { System.out.println("Ongeldige invoer. Opnieuw!"); } catch (IOException exception) // de meest algemene class // aan het eind zetten { System.out.println("Invoerprobleem. Stop!"); System.exit(0); } }// einde while-lus return getal; }// einde functie } JAVA -- H14

  16. Voorbeeld 2 :Eenvoudiger oplossing voor input met swing-functies import javax.swing.*; class Gebruiker_lees { public static int getInteger(String prompt) { int getal = 0; boolean geldig = false; String input; while (! geldig) { input = JOptionPane.showInputDialog(prompt); enz... JAVA -- H14

  17. Voorbeeld 3: een geheel getal ingeven in een tekstvak en de dubbele waarde tonen in een ander tekstvak na een enterhit public class ExceptionDemo extends JApplet implements ActionListener { private JTextField invoerVak; private JTextField resultaat; private JLabel resultLabel, tekstLabel; JAVA -- H14

  18. public void init() • { Container c = getContentPane(); c.setLayout(new FlowLayout()); • tekstLabel = new JLabel("Geef een geheel getal: "); • resultLabel = new JLabel("Antwoord "); • invoerVak = new JTextField(20); • resultaat = new JTextField(30); • resultaat.setEditable(false); // niet wijzigen! • c.add(tekstLabel); c.add(invoerVak); • invoerVak.addActionListener(this); // enterhit! • c.add(resultaat); c.add(resultLabel); • } JAVA -- H14

  19. public void actionPerformed (ActionEvent event) { if (event.getSource() == invoerVak) { try { int getal = Integer.parseInt(invoerVak.getText()); resultaat.setText("Verdubbelde waarde is " + (2 * getal)); } catch (NumberFormatException e) { resultaat.setText("Fout in getal: herbegin "); } finally {invoerVak.setText(""); invoerVak.requestFocus(); } } // einde if } // einde actionPerformed }// einde klasse JAVA -- H14

  20. 6. Gooien van een exception • Het throw statement • duidt aan dat er een exception is voorgekomen • de operand kan van elke klasse zijn die afgeleid is van de klasse Throwable • Subklassen van Throwable • Class Exception • Problemen die opgevangen moeten worden -> programma robuster! • Class Error • Ernstige exceptions, die niet moeten opgevangen worden • Wanneer een exception optreedt in een try block, dan wordt deze blok verlaten (zelfs als het throw punt in een geneste blok zit) en wordt verdergegaan met het corresponderende catch block JAVA -- H14

  21. 7. Vangen van een exception • Een catch-blok handelt een bepaalde soort exceptie af. • Elk catch-blok start met het keyword catch, gevolgd door een parameterlijst met één parameter, die aangeeft welk soort exceptie kan opgevangen worden. • Het programma stopt als er geen geschikte handler is. • Eén catcher kan meerdere exceptions afhandelen: • catch (Exception e) { // ….} // “catch-all” handler JAVA -- H14

  22. 7. Vangen van een exception (2) • De eerste catcher na een try-blok die overeenkomt met het exception-type wordt uitgevoerd; alle andere worden genegeerd! • Zet nooit een catcher van een superklasse object vóór een catcher van een subklasse object! • Een exception kan op verschillende wijzen afgehandeld worden. • Het is niet mogelijk om nog terug te keren naar het throw punt! JAVA -- H14

  23. 8. Voorbeeld : de exceptie “delen door 0” afhandelen • Standaard gooit Java een exception van de klasse ArithmeticException wanneer er door nul wordt gedeeld bij integers! Delen door nul is in Java toegelaten bij floating-point variabelen. • In het volgende voorbeeld wensen we echter de gebruiker van ons programma er op te wijzen dat hij door nul probeert te delen (ook bij floating-point)! • De methode quotient gooit een exceptie van een nieuw type (DivideByZeroException) wanneer deze een nul ontvangt als tweede argument. JAVA -- H14

  24. 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) • Wanneer we een eigen exceptieklasse ontwerpen, dan moet deze afgeleid zijn van een Java API exceptieklasse (eventueel Exception)! • Een typische exceptieklasse bevat enkel twee constructoren, één constructor zonder argument welke een default exceptieboodschap specifieert en een constructor met één argument, die een foutboodschap ontvangt als een String. JAVA -- H14

  25. 1 // Fig. 14.1: DivideByZeroException.java 2 // Definitie van de class DivideByZeroException. 3 // Wordt gebruikt om een exceptie te gooien wanneer een 4 // deling door nul voorkomt. 5 public class DivideByZeroException extends ArithmeticException 6 { 7 // constructor zonder argument, specifieert de default error message 8 public DivideByZeroException() 9 { 10 super( "Attempted to divide by zero" ); 11 } 12 13 // constructor met een parameter 14 public DivideByZeroException( String message ) 15 { 16 super( message ); 17 } 18 19 } // end class DivideByZeroException 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) JAVA -- H14

  26. 1 // Fig. 14.2: DivideByZeroTest.java 2 // een eenvoudig voorbeeld van exception handling 3 // Controle op een divide-by-zero-error. 4 5 import java.awt.*; 6 import java.awt.event.*; 7 import java.text.DecimalFormat; 8 9 import javax.swing.*; 10 11 public class DivideByZeroTest extends JFrame implements ActionListener 12 { 13 private JTextField inputField1, inputField2, outputField; 14 privateint number1, number2; 15 private double result; 16 17 // set up GUI 18 public DivideByZeroTest() 19 { 20 super( "Demonstrating Exceptions" ); 21 22 // get content pane and set its layout 23 Container container = getContentPane(); 24 container.setLayout( new GridLayout( 3, 2 ) ); 25 26 // set up label and inputField1 27 container.add( new JLabel( "Enter numerator ", SwingConstants.RIGHT ) ); 28 inputField1 = new JTextField( 10 ); 29 container.add( inputField1 ); 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) JAVA -- H14

  27. 35 // set up label and inputField2; register listener 36 container.add( new JLabel( "Enter denominator and press Enter ", SwingConstants.RIGHT ) ); 37 inputField2 = new JTextField( 10 ); 38 container.add( inputField2 ); 39 inputField2.addActionListener( this ); 40 41 // set up label and outputField 42 container.add( new JLabel( "RESULT ", SwingConstants.RIGHT ) ); 43 outputField = new JTextField(); 44 container.add( outputField ); 45 46 setSize( 425, 100 ); 47 setVisible( true ); 48 } 49 50 // process GUI events 51 public void actionPerformed( ActionEvent event ) 52 { 53 DecimalFormat precision3 = new DecimalFormat( "0.000" ); 54 55 outputField.setText( "" ); // clear outputField 56 57 // read two numbers and calculate quotient 58 try { 59 number1 = Integer.parseInt( inputField1.getText() ); 60 number2 = Integer.parseInt( inputField2.getText() ); 61 62 result = quotient( number1, number2 ); 63 outputField.setText( precision3.format( result ) ); 64 } 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) JAVA -- H14

  28. 65 // de catcher die uitgevoerd wordt, wanneer de input van een verkeerd formaat is 66 catch ( NumberFormatException numberFormatException ) 67 { 68 JOptionPane.showMessageDialog( this, "You must enter two integers", 69 "Invalid Number Format",JOptionPane.ERROR_MESSAGE ); 70 } 71 72 // de catcher die uitgevoerd wordt, wanneer er door nul wordt gedeeld 73 catch ( ArithmeticException arithmeticException ) 74 { JOptionPane.showMessageDialog( this, arithmeticException.toString(), 75 "Arithmetic Exception",JOptionPane.ERROR_MESSAGE ); 76 } 77 } 78 79 // methode quotient gooit een exceptie wanneer een divide-by-zero error optreedt 80 public double quotient( int numerator, int denominator ) throws DivideByZeroException 81 { 82 if ( denominator == 0 ) 83 thrownew DivideByZeroException(); 84 85 return ( double ) numerator / denominator; 86 } 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) JAVA -- H14

  29. 87 // execute application 88 public static void main( String args[] ) 89 { 90 DivideByZeroTest application = new DivideByZeroTest(); 91 92 application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 93 } 94 95 } // end class DivideByZeroTest 8. Voorbeeld : de exceptie “delen door 0” afhandelen (2) JAVA -- H14

  30. Oefening 1 We hernemen een oefening van H. 11: Schrijf een applicatie die een temperatuur in Fahrenheit omzet in een temperatuur in Celsius. De temperatuur in Fahrenheit wordt via het toetsenbord ingevoerd (JTextField). Via een JLabel wordt de geconverteerde temperatuur afgedrukt. Zorg ervoor dat een foutieve input (= niet numeriek, buiten de grenzen van het interval [-10°C,40°C]) wordt gemeld met een duidelijke foutboodschap in een dialoogvenster. Wanneer dit venster wordt gesloten, moet het inputveld terug leeg zijn en moet de cursor in dit veld staan wachten. Handel de fouten ter plaaste af! JAVA -- H14

  31. 9. De exceptie opnieuw gooien Gooi de exceptie opnieuw, als de catch deze niet kan afhandelen of deze wil doorgeven aan een andere catcher: throw exceptionReference; Een dergelijk statement gooit de exceptie naar de volgende try-blok en deze wordt afgehandeld door een exception handler na dit blok. JAVA -- H14

  32. 10. De throws-clausule • geeft een lijst van de excepties die door de methode kunnen gegooid worden:intfunctionName(paramterList)throwsExceptionType1, ExceptionType2,…{// method body} • Deze methode kan zowel objecten van de aangegeven klassen gooien als objecten van hun subklassen! • het is niet noodzakelijk om alle exceptions en errors, die door de methode kunnen gegooid worden, in de lijst op te nemen! JAVA -- H14

  33. 10. De throws-clausule (2) • Errors en unchecked RuntimeExceptions moeten niet expliciet gepropageerd worden d.m.v. een throws-clausule! • ArrayIndexOutOfBoundsException • NullPointerException, … (zie p. 822) • Alle checked exceptions moeten in de throws-clausule voorkomen, m.a.w. ze moeten expliciet gepropageerd worden! • Wanneer we een methode met throws-clausule uit de superklasse in een subklasse opnieuw definiëren, dan moet deze nieuwe versie dezelfde lijst van excepties hebben of een deelverzameling van de lijst! JAVA -- H14

  34. 10. De throws-clausule (2) – impliciete propagatie (voorbeeld) 4 Indien nergens iets voorzien wordt, komen we bij de main en stopt het programma met een foutmelding main 3 methodeA De exception volgt de weg terug. methodeX 2 methodeY throws de exception 1 In methodeY doet zich een exception voor methodeY JAVA -- H14

  35. Voorbeeld (1) class Propagation_Demo { public static void main(String[] args) { Exception_Scope demo = new Exception_Scope(); System.out.println("Begin van het programma"); demo.level1(); System.out.println("Einde van het programma"); } } JAVA -- H14

  36. Voorbeeld (2) class Exception_Scope { public void level3(int adjustment) { int huidig = 1; System.out.println(" start level3 "); huidig = huidig / adjustment; System.out.println(" einde level3 "); } JAVA -- H14

  37. Voorbeeld (3) public void level2() { System.out.println(" start level2 "); level3(0); System.out.println(" einde level2 "); } JAVA -- H14

  38. Voorbeeld (4) public void level1() { System.out.println(" start level1 "); try { level2(); } catch (ArithmeticException probleem) {System.out.println(probleem.getMessage()); probleem.printStackTrace(); } System.out.println(" einde level1 "); } } JAVA -- H14

  39. Uitvoer voorbeeld JAVA -- H14

  40. 11. Constructoren, finalizers en exception handling • Wanneer er een fout in de constructor gedetecteerd • wordt, wordt er een exceptie gegooid naar de code die • het object wenst te creëeren. • De methode finalize wordt automatisch aangeroepen, • vóór een object als afval wordt gecollecteerd. JAVA -- H14

  41. 12. Excepties en overerving • Een catcher die uitgewerkt is om excepties op te vangen • van een bepaalde klasse X, kan ook alle excepties van de • subklassen van X opvangen. • Wanneer we echter een verschillende afhandeling wensen • per type exceptie, dan moeten we opsplitsen en meerdere • catchers voorzien. Om te vermijden dat één vergeten wordt, • is het veilig om de lijst van de catchers af te sluiten met de • catcher voor de superklasse. JAVA -- H14

  42. 13. Het finally-blok • Resource leak • Noodzakelijk wanneer resources niet vrijgegeven worden door een programma. Bijvoorbeeld het sluiten van files geopend in de try-blok. • De finally blok • Staat altijd achter alle catch blokken. • Wordt ALTIJD uitgevoerd. • Wordt gebruikt om resources terug vrij te geven. JAVA -- H14

  43. 13. Het finally-blok (2) • definieert de verplichte uitvoering van een stukje code • meestal gebruikt om bv. bestanden e. d. af te sluiten indien er zich een foutsituatie heeft voorgedaan • mogelijke situaties: • als er in een try-blok GEEN fout optreedt, wordt nadien het finally-blok uitgevoerd, zelfs als er in het try-blok een return of break staat • als er een fout optreedt in het try-blok, die niet kan opgevangen worden, dan wordt eerst het finally-blok uitgevoerd en vervolgens wordt de fout gepropageerd JAVA -- H14

  44. 13. Het finally-blok (3) • de fout die zich voordoet in het try-blok, wordt opgevangen in het catch-blok en vervolgens wordt het finally-blok uitgevoerd: • String regel; • try { while ((regel = mijnBestand.readLine()) != null) • { // verwerk regel } • } • catch (IOException e) • { errorField.setText("Fout in invoerbestand");} • finally • { mijnBestand.close();} JAVA -- H14

  45. Voorbeeld Gebruik van een finally-blok JAVA -- H14

  46. 1 // Fig. 14.9: UsingExceptions.java 2 // Demonstratie van try-catch-finally 3 // exception handling mechanisme. 4 public class UsingExceptions 5 { 6 // uitvoeren application 7 public static void main( String args[] ) 8 { 9 // methode throwException aanroepen 10 try { 11 throwException(); 12 } 13 14 // catch Exceptions gegooid door de methode throwException 15 catch ( Exception exception ) 16 { 17 System.err.println( "Exception handled in main" ); 18 } 19 20 doesNotThrowException(); 21 } 22 23 // demonstratie van try/catch/finally 24 public static void throwException() throws Exception 25 { 26 // gooi een exceptie en catch het onmiddellijk 27 try { 28 System.out.println( "Method throwException" ); 29 throw new Exception(); // generate exception 30 } 13. Het finally blok • Resource leak • Caused when resources are not released by a program • The finally block • Appears after catch blocks • Always executes • Use to release resources JAVA -- H14

  47. 32 // catch exception gegooid in try block 33 catch ( Exception exception ) 34 { 35 System.err.println( 36 "Exception handled in method throwException" ); 37 throw exception; // gooi opnieuw voor verdere uitvoering 38 // elke code die hier staat wordt nooit bereikt! 39 } 40 41 // dit blok wordt uitgevoerd, ongeacht wat in try/catch staat 42 finally { 43 System.err.println( "Finally executed in throwException" ); 44 } 45 // elke code die hier staat wordt nooit bereikt! 46 } 47 48 // finaal, demonstratie wat er gebeurt als er geen exceptie optreedt 49 public static void doesNotThrowException() 50 { 51 // try block gooit geen exceptie 52 try { 53 System.out.println( "Method doesNotThrowException" ); 54 } 55 56 // catch wordt niet uitgevoerd, want er wordt geen exceptie gegooid 57 catch( Exception exception ) 58 { 59 System.err.println( exception.toString() ); 60 } 61 13. Het finally blok • Resource leak • Caused when resources are not released by a program • The finally block • Appears after catch blocks • Always executes • Use to release resources JAVA -- H14

  48. 66 // dit blok wordt uitgevoerd ongeacht wat er gebeurt in de try/catch 67 finally { 68 System.err.println("Finally executed in doesNotThrowException" ); 69 } 70 71 System.out.println( "End of method doesNotThrowException" ); 72 } 73 74 } // einde class UsingExceptions 13. Het finally blok Method throwException Exception handled in method throwException Finally executed in throwException Exception handled in main Method doesNotThrowException Finally executed in doesNotThrowException End of method doesNotThrowException ! Output v/h programma JAVA -- H14

  49. Voorbeeld Demonstratie van “stack-unwinding” JAVA -- H14

  50. 1 // Fig. 14.10: UsingExceptions.java 2 // Demonstratie van de “stack-unwinding”. 3 public class UsingExceptions 4 { 5 // uitvoeren application 6 public static void main( String args[] ) 7 { 8 // roep de methode throwException om de “stack-unwinding” te demonstreren 9 try { 10 throwException(); 11 } 12 13 // catch exception gegooid in throwException 14 catch ( Exception exception ) 15 { System.err.println( "Exception handled in main" ); 16 } 17 } 13. Het finally blok JAVA -- H14

More Related