JAVA -- H81 Exception: ongewone of foutieve situatie->prog. mislukt 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() Error kan niet hersteld worden (interne fouten in de run-time omgeving van JVM) EXCEPTION HANDLING - SOORTEN
JAVA -- H82 Klassenhiërarchie van de belangrijkste errors en exceptions: Throwable (= superklasse) Error (unchecked) LinkageError VirtualMachineError OutOfMemoryError EXCEPTION HANDLING - SOORTEN
JAVA -- H83 EXCEPTION HANDLING - SOORTEN Exception (allemaal checked, behalve RunTimeException) RunTimeException (unchecked) ArithmeticException IndexOutofBoundsException ArrayIndexOutofBoundsException IllegalArgumentException NumberFormatException IOException (checked) FileNotFoundException MalformedURLException InterruptException (checked)
JAVA -- H84 EXCEPTION HANDLING - OPLOSSINGEN helemaal niets, geen speciale code in het programma -> systeemfoutboodschap (1) afhandeling op de plaats waar de fout optreedt -> try-catch-finally-statement (2) afhandeling op een andere plaats -> impliciete of expliciete exception propagation (3)
JAVA -- H85 EXCEPTION HANDLING - (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 -- H86 EXCEPTION HANDLING – (2) controle op de instructies waarin zich fouten kunnen voordoen; als er een fout optreedt, dan wordt er een instantie van een exception-class gemaakt: try-gedeelte hoe opvangen van de fout; meerdere catch- clausules mogelijk; elk verwerkt een bepaald soort fout: catch-gedeelte code die hoe dan ook moet uitgevoerd worden: finally-gedeelte [ optioneel]
JAVA -- H87 EXCEPTION HANDLING -- TRY-STATEMENT Voorbeeld 1: try { int a[]= new int[2]; a[5] = 1; } catch(ArrayIndexOutOfBoundsException fout) { System.out.println(“Fout:” + fout.getMessage());}
JAVA -- H88 EXCEPTION HANDLING – TRY STATEMENT 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 -- H89 EXCEPTION HANDLING – TRY STATEMENT 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 -- H810 EXCEPTION HANDLING – TRY STATEMENT 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 -- H811 EXCEPTION HANDLING – TRY STATEMENT Voorbeeld 3: geheel getal ingeven en verdubbelen public class ExceptionDemo extends Applet implements ActionListener { private TextField invoervak; private TextField resultaat; private Label resultLabel, tekstLabel;
JAVA -- H812 EXCEPTION HANDLING – TRY STATEMENT public void init() { tekstLabel = new Label("Geef een geheel getal: "); resultLabel = new Label("Antwoord "); invoerVak = new TextField(20); resultaat = new TextField(30); resultaat.setEditable(false); // niet wijzigen! add(tekstLabel); add(invoerVak); invoerVak.addActionListener(this); // enterhit! add(resultaat); add(resultLabel); }
JAVA -- H813 EXCEPTION HANDLING – TRY STATEMENT 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 "); } }
JAVA -- H814 EXCEPTION HANDLING – (3 - impliciet) fouten worden NIET ter plaatse afgehandeld controle wordt teruggegeven aan de aanroepende methode propagatie tot fout wordt opgevangen of tot main- methode (->systeemfoutboodschap) methode-aanroep moet in een try-catch-statement staan om de fout te kunnen opvangen
JAVA -- H815 EXCEPTION HANDLING – IMPLICIETE PROPAGATION main methodeA methodeX methodeY In methodeY doet zich een exception voor methodeY throws de exception De exception volgt de weg terug. Indien nergens iets voorzien wordt, komen we bij de main en stopt het programma met een foutmelding
JAVA -- H816 EXCEPTION HANDLING – IMPLICIETE PROPAGATION -- VOORBEELD 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 -- H817 EXCEPTION HANDLING – IMPLICIETE PROPAGATION -- VOORBEELD 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 -- H818 EXCEPTION HANDLING – IMPLICIETE PROPAGATION -- VOORBEELD public void level2() { System.out.println(" start level2 "); level3(0); System.out.println(" einde level2 "); }
JAVA -- H819 EXCEPTION HANDLING – IMPLICIETE PROPAGATION -- VOORBEELD 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 -- H820 EXCEPTION HANDLING – IMPLICIETE PROPAGATION – UITVOERING VOORBEELD
JAVA -- H821 EXCEPTION HANDLING – (3 - expliciet) = sommige fouten worden vanuit Java standaard gecontroleerd = Checked exceptions Vb.: lezen van een bestand kan een IOException veroorzaken de code moet hiertegen beveiligd worden Hoe? * Gebruik maken van de throws-clausule (= expliciete propagation) * een try-statement gebruiken
JAVA -- H822 EXCEPTION HANDLING – EXPLICIETE PROPAGATION -- VOORBEELD we gebruiken de klasse BigInteger, een subklasse van math, om met zéér grote getallen te kunnen werken een object van de klasse ArrayList is een “dynamische” array, m.a.w deze kan ‘onbeperkt’ groeien de methode ‘factorial’ is “synchronized”: hierdoor kan ze ‘gesynchroniseerd’ in meerdere threads (gelijktijdig) gebruikt worden
JAVA -- H823 EXCEPTION HANDLING – EXPLICIETE PROPAGATION -- VOORBEELD import java.math.BigInteger; import java.util.*; public class Factorial { protected static ArrayList table = new ArrayList(); // A "static initializer" : static { //Initialize the first element of the cache with 0!=1 table.add(BigInteger.valueOf(1)); }
JAVA -- H824 EXCEPTION HANDLING – EXPLICIETE PROPAGATION -- VOORBEELD public static synchronized BigInteger factorial(int x) {if (x<0) throw new IllegalArgumentException("x mag niet negatief zijn"); for(int size = table.size(); size <= x; size++) {BigInteger lastfact = (BigInteger)table.get(size-1); BigInteger nextfact = lastfact.multiply(BigInteger.valueOf(size)); table.add(nextfact); } return (BigInteger) table.get(x); } }
JAVA -- H825 EXCEPTION HANDLING – EXPLICIETE PROPAGATION – CLASS FACT1 public class Fact1 //werken met programmaparameters: mogelijke // fouten: ofwel geen argument, ofwel geen getal { public static void main(String[] args) { try { int x = Integer.parseInt(args[0]); System.out.println(x + "! = " + Factorial.factorial(x)); } catch (ArrayIndexOutOfBoundsException e) { System.out.println(“Je moet een argument ingeven!"); System.out.println("Usage: java Fact1 "); }
JAVA -- H826 EXCEPTION HANDLING – EXPLICIETE PROPAGATION – CLASS FACT1 // Indien het argument geen getal is; thrown door parseInt catch (NumberFormatException e) { System.out.println(“Je moet een geheel getal ingeven"); } // Indien het argument <0; thrown door factorial catch (IllegalArgumentException e) { // Toon het bericht uit de factorial-methode: System.out.println(“Slecht argument: " + e.getMessage()); }
JAVA -- H827 EXCEPTION HANDLING – EXPLICIETE PROPAGATION – CLASS FACT2 import java.io.*; // class IOException public class Fact2 // invoer van verschillende getallen { public static void main(String[] args) throws IOException //want checked exception bij inlezen { BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); for(;;) { System.out.print("Fact2> "); // toont een prompt op het scherm String line = in.readLine(); // inlezen van de invoer
JAVA -- H828 EXCEPTION HANDLING – EXPLICIETE PROPAGATION – CLASS FACT2 if ((line == null) || line.equals("quit")) break; try { int x = Integer.parseInt(line); System.out.println(x + "! = " + Factorial.factorial(x)); } // Als er iets fout gaat, tonen we een algemene melding catch(Exception e) { System.out.println(“Ongeldige invoer"); } } // de for-lus } // main() }
JAVA -- H829 EXCEPTION HANDLING – EIGEN EXCEPTION KLASSE zelf een foutsituatie creëren, controleren en afhandelen subklasse van een bestaande “fout”klasse aanmaken het throw-statement start de afhandeling throw-statement in een if-statement plaatsen
JAVA -- H830 EXCEPTION HANDLING – EIGEN EXCEPTION KLASSE -- VOORBEELD public class Exceptie { public static void main(String[] args) //werken met progpar. { int i = 0; try { if (args.length == 0) throw new MijnExceptie("Programma- argument ontbreekt!"); i = Integer.parseInt(args[0]); if (i == 0) throw new MijnExceptie("Noemer nul!"); System.out.println("1000 / " + i + " = " /i); }
JAVA -- H831 EXCEPTION HANDLING – EIGEN EXCEPTION KLASSE -- VOORBEELD catch (NumberFormatException e) // parseInt { System.out.println("Argument ongeldig!"); } catch (Exception e) { System.out.println(e); }
JAVA -- H832 EXCEPTION HANDLING – EIGEN EXCEPTION KLASSE -- VOORBEELD class MijnExceptie extends Exception {private String s; MijnExceptie(String s) { this.s = s;} public String toString() { return s;} }
JAVA -- H833 EXCEPTION HANDLING – FINALLY 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 -- H834 EXCEPTION HANDLING – FINALLY: VOORBEELD > 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();}