Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11 Undantag Engelska: exceptions Skansholm: exceptionella händelser Fel som genereras om man försöker öppna en fil som inte finns, dividera med noll, indexera utanför en array osv. 1 3 Olika typer av fel Kompileringsfel: programkoden följer inte Javas regler Exekveringsfel: fel som uppstår när programmet körs och medför att programmet inte kan fortsätta exekvera. Exempel: en fil som ska öppnas saknas, använding av referensvariabel som inte refererar något objekt. Logiska fel: programmet gör inte det vi väntade oss Exekveringsfel handlar ofta om problem som ligger utanför programmet, tex felaktigt indata Exempel: Skriv ett program som 1. ber om ett filnamn 2. öppnar filen 3. läser innehållet 4. gör nåt med innehållet 5. stänger filen Alla operationer kan gå snett! 2 4
Motivation (forts) En lösning: skriv uttryckliga tester för alla felsituationer h = open_file(...) if (h.error) { // hantera felet else { // fortsätt att läsa filen Om man ska hantera alla felsituationen blir kontrollflödet komplicerat! Dessutom: det är svårt att testa koden. Man måste provköra med alla kombinationer av felsituationer. class A { class B extends A { class Exce2 { A x = new A(); B y = (B)x; $ java Exce2 java.lang.classcastexception: A at Exce2.main(Exce2.java:8) 5 7 Exempel class Exce1 { static void p () { int x = 1/0; p(); $ java Exce1 java.lang.arithmeticexception: / by zero at Exce1.p(Exce1.java:3) at Exce1.main(Exce1.java:7) class Exce3 { int x = Integer.parseInt(arg[0]); System.out.println(x*x); 6 8
$ java Exce3 42 1764 $ java Exce3 kaka java.lang.numberformatexception: kaka at java.lang.integer.parseint(integer.java:414) at java.lang.integer.parseint(integer.java:463) at Exce3.main(Exce3.java:3) $ java Exce3 java.lang.arrayindexoutofboundsexception at Exce3.main(Exce3.java:3) Typer av undantag Ett undantag i Java är ett objekt av någon subklass till klassen java.lang.throwable. Undantagen kan delas upp i tre grupper: Error (Fel) Run-time exception Checked exception (Kontrollerade undantag) 9 11 Typer av undantag (forts) Undantag Frågor om undantag. Vilka typer av undantag finns det? Hur genereras dem? Hur kan man hantera dem? Error Fel som vanligtvis inte kan hanteras, tex att maskinen har slut på minne. Run-time exception Vanliga programfel, tex division med noll, fel i arrayindexering, fel i typkonvertering, eller access av null-objekt. Kontrollerade undantag Fel som rimligtvis bör hanteras av programmet, till exempel försök att öppna en fil som inte finns. 10 12
De viktigaste typerna av undantag Typer av undantag (forts) Vilket typ av undantag? Object Ett undantag tillhör gruppen Error Throwable om det tillhör en klass som ärver från java.lang.error Ett undantag tillhör gruppen Run-time Exception Error Exception om det tillhör en klass som ärver från java.lang.runtimeexception Kontrollerade undantag RunTimeException Tips: RuntimeException har en konstruktor som tar Throwable som argument... Alla andra undantag tillhör gruppen Checked Exception. 13 15 Typer av undantag (forts) Det finns två viktiga klasser som ärver direkt från Throwable, java.lang.error och java.lang.exception Exempel: IOException java.lang.exception har en viktig subklass java.lang.runtimeexception 14 16
Att kasta ett undantag (Generera exceptionella händelser) class Undantag extends Exception { class A { void m() throws Undantag { throw new Undantag(); Hantera undantag Exempel class Exce5 { void m() throws Undantag { throw new Undantag(); static void main(string [] arg) { Exce5 x = new Exce5(); try { x.m(); catch (Undantag e) { System.out.println("Ett undantag..."); 17 19 Kasta undantag (forts) Notera: Vi måste deklarera att metoden m kastar undantag (och vilken typ av undantag). Detta gäller för alla kontrollerade undantag (checked exceptions). Undantag skapas med new (som alla andra objekt). hantera undantag (forts) En sats try {... catch (U e) { hantera felet evaluerar... och fångar alla fel av klassen U 18 20
Exempel: try-catch 2 class Exce6 { static int div (int x, int y) { int r; try { r = x / y; catch (ArithmeticException e) { r = 0; return r; Exempel: try-catch 2 (körexempel) harpo$ java Exce6 java.lang.arrayindexoutofboundsexception: 0 at Exce6.main(Exce6.java:13) harpo$ java Exce6 100 7 14 harpo$ java Exce6 100 0 0 harpo$ q 21 23 Exempel: try-catch 2 (forts) int x = Integer.parseInt(arg[0]); int y = Integer.parseInt(arg[1]); int z = div(x,y); System.out.println(z); Att passa ett undantag vidare Vad händer om en metod inte fångar ett kontrollerat undantag? För att den saknar en try-sats, eller för att try-satsen inte fångar just den typen av undantag. Undantaget passas vidare till anroparen. Vilket innebär att anroparen också måste deklarera undantaget. 22 24
När körs finally-delen? (forts) Mer om try-satser En try-sats kan ha flera catch-klausuler plus en finally-klausul. try {... catch (U e) { hantera U catch (V e) { hantera V finally { avslutning 1. Normal terminering. Finally-delen körs efter att {... terminerat 2. Undantag kastas och hanteras av en catch. Finally-delen körs efter att hanteraren körts. 3. Undantag kastas men hanteras inte. Finally-delen körs före undantaget passas vidare. Finally-delen körs alltid. Bra för att (tex) stänga filer. (Men close() kan kasta en IOException som måste fångas...) 25 27 Finally När körs finally-delen? En try kan terminera på tre olika sätt. 1. {... terminerar normalt. 2. {... kastar ett undantag som hanteras av en catch-klausul. 3. {... kastar ett undantag som inte hanteras. Sammanfattning Alla fel som uppstår vid körning representeras som undantag Undantag är objekt i någon subklass till Throwable Undantag kan hanteras (med try-catch) eller deklarertas (med throws) Vissa undantag (kontrollerade undantag, eller checked exceptions) måste deklareras; om en metod kan kasta ett sådant måste den deklarera det 26 28