Kapittel 11: Unntakshåndtering. Java som første programmeringsspråk

Like dokumenter
Kapittel 11: Unntakshåndtering. Java som første programmeringsspråk

Kapittel 13: Unntakshåndtering

Kapittel 13: Unntakshåndtering

INF1010 våren 2017 Onsdag 25. januar. Litt om unntak i Java

INF1010 våren 2019 Onsdag 30. januar. Mer om unntak i Java (med litt repetisjon av I/O først)

INF1010 våren 2018 tirsdag 23. januar

Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

INF 1010, vår 2005 Løsningsforslag uke 11

Inf1010 Våren Feilsituasjoner og unntak i Java. Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

Læringsmål for forelesningen

Inf1010 Våren Feilsituasjoner og unntak i Java. Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

Oversikt. Feil i programmet hva skjer? Array indeks utenfor sine grenser. Inf1010 Våren Feilsituasjoner og unntak i Java

Oversikt. Feil i programmet hva skjer? Array indeks utenfor sine grenser. Inf1010 Våren Feilsituasjoner og unntak i Java

Inf1010 Våren Feilsituasjoner og unntak i Java. Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

Kapittel 7: Mer om arv

Kapittel 1: Datamaskiner og programmeringsspråk

Leksjon 7. Filer og unntak

Oversikt. Array indeks utenfor sine grenser. Feil i programmet hva skjer?

INF1010 våren Arv og subklasser - del 2

Kapittel 1: Datamaskiner og programmeringsspråk

INF1010 våren Arv og subklasser del 1 (pluss litt I/O og unntaksbehandling)

Kapittel 8: Programutvikling

D Feilhåndtering og unntaksklasser

Jentetreff INF1000 Debugging i Java

Videregående programmering 6

Kapittel 9: Sortering og søking Kort versjon

2 Om statiske variable/konstanter og statiske metoder.

Konstruktører. Bruk av konstruktører når vi opererer med "enkle" klasser er ganske ukomplisert. Når vi skriver. skjer følgende:

INF1010 våren Arv og subklasser del 1 pluss (hvis vi har tid) litt om Unntak, IO og Scanner-klassen

Kapittel 8: Sortering og søking INF100

Klasser skal lages slik at de i minst mulig grad er avhengig av at klienten gjør bestemte ting STOL ALDRI PÅ KLIENTEN!

Kapittel 8: Sortering og søking INF100

IN Notat om I/O i Java

INF1010 våren Generalisering -spesialisering Gjenbruk av klasser. Ved arv. Klasse-hierarkier. Stein Gjessing.

Forkurs INF1010. Dag 2. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 14.

Kapittel 8: Sortering og søking

Innhold. Forord Det første programmet Variabler, tilordninger og uttrykk Innlesing og utskrift...49

Kapittel 5: Objektkommunikasjon

Kapittel 13: Grafiske brukergrensesnitt INF 100. Java som første programmeringsspråk

Forklaring til programmet AbstraktKontoTest.java med tilhørende filer Konto.java, KredittKonto.java, SpareKonto.java

Leksjon 7. Filer og unntak

TOD063 Datastrukturer og algoritmer

Kapittel 1. Datamaskiner og programmeringsspråk. 1.1 Programmering

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Eksekveringsrekkefølgen (del 1) Oppgave 1. Eksekveringsrekkefølgen (del 2) Kommentar til oppgave 1. } // class Bolighus

2 Om statiske variable/konstanter og statiske metoder.

Kapittel 6: Arv. Redigert av: Khalid Azim Mughal

Uke 5, 27. januar Arv og subklasser del I. Stein Gjessing Institutt for informatikk

Kapittel 15: Grafiske brukergrensesnitt: Enkel GUI. Del I

Kapittel 15: Grafiske brukergrensesnitt: Enkel GUI. Del I

I et Java-program må programmøren lage og starte hver tråd som programmet bruker. Er dette korrekt? Velg ett alternativ

INF1000: Forelesning 4. Mer om arrayer Metoder

Eksamen. Objektorientert Programmering IGR 1372

Kapittel 9: Sortering og søking Kort versjon


Forkurs INF1010. Dag 3. Andreas Færøvig Olsen Gard Inge Rosvold Institutt for Informatikk, 15.

Forkurs INF1010. Dag 3. Andreas Færøvig Olsen Eivind Storm Aarnæs

INF1010, 22. mai Prøveeksamen (Eksamen 12. juni 2012) Stein Gjessing Inst. for Informatikk Universitetet i Oslo

Strukturering av programmer

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister

Av Stein Gjessing, Institutt for informatikk, Universitetet i Oslo

INF Notat om I/O i Java

Hva er verdien til variabelen j etter at følgende kode er utført? int i, j; i = 5; j = 10; while ( i < j ) { i = i + 2; j = j - 1; }

TDT4100 Objektorientert programmering

UNIVERSITETET I OSLO

Å lese tall fra en fil, klassen Scanner

Post-it spørsmål fra timen (Arv og subklasser)

INF 1000 (uke 2) Variabler, tilordninger og uttrykk

Kapittel 1: Datamaskiner og programmeringsspråk. Java som første programmeringsspråk

Kort om meg. INF1000 Uke 2. Oversikt. Repetisjon - Introduksjon

Kapittel 1: Datamaskiner og programmeringsspråk. Java som første programmeringsspråk

1. Tråder og socketprogrammering.

INF1000 : Forelesning 4

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

INF 1000 høsten 2011 Uke september

Oppsummering. Kort gjennomgang av klasser etc ved å løse halvparten av eksamen Klasser. Datastrukturer. Interface Subklasser Klasseparametre

Array&ArrayList Lagring Liste Klasseparametre Arrayliste Testing Lenkelister Videre

MER OM ARRAYER. INF1000: Forelesning 4. Anta at vi ønsker å lagre en liste med navnene på alle INF1000-studentene:

i=0 i=1 Repetisjon: nesting av løkker INF1000 : Forelesning 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker j=0 j=1 j=2 j=3 j=4

ADT og OO programmering

INF1000 undervisningen INF 1000 høsten 2011 Uke september

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

Kapittel 9: Sortering og søking Kort versjon

INF1010 våren 2008 Uke 4, 22. januar Arv og subklasser

Kapittel 9: Sortering og søking Kort versjon

Oversikt. INF1000 Uke 1 time 2. Repetisjon - Introduksjon. Repetisjon - Program

Fra Python til Java. En introduksjon til programmeringsspråkenes verden. Dag Langmyhr

public static <returtype> navn_til_prosedyre(<parameter liste>) { // implementasjon av prosedyren

UNIVERSITETET I OSLO

IN 211 Programmeringsspråk. Java. på 20 enkle ark. spesielt for de som kan. Simula. (og gjerne litt C) Ark 1 av 20

Forelesning inf Java 4

Del 3: Evaluere uttrykk

i=0 Repetisjon: arrayer Forelesning inf Java 4 Repetisjon: nesting av løkker Repetisjon: nesting av løkker 0*0 0*2 0*3 0*1 0*4

Repitisjonskurs. Arv, Subklasser og Grensesnitt

UNIVERSITETET I OSLO

INF Notater. Veronika Heimsbakk 10. juni 2012

INF1010 våren Arv og subklasser - del 2

Fra Python til Java, del 2

Transkript:

Kapittel 11: Unntakshåndtering Forelesningsnotater for: Java som første programmeringsspråk Khalid Azim Mughal, Torill Hamre, Rolf W. Rasmussen Cappelen Akademisk Forlag, 2003. ISBN 82-02-23274-0 http://www.ii.uib.no/~khalid/jfps/ Vi gir tillatelse til å bruke disse notatene i tilknytning til boken. Modifisert: 16/1/06 JFPS 11: Unntakshåndtering 11-1/45 Emneoversikt Programutføring "kast og fang"-prinsippet Unntakspropagering Typiske scenarier ved bruk av try-catch-setning Utdrag av unntaksklasser Eksplisitt kast av unntak: throw-klausul try-blokk med flere catch-blokker Typiske programmeringsfeil ved unntakshåndtering Håndtering av kontrollerte unntak og throws-klausul Utføring av finally-blokk JFPS 11: Unntakshåndtering 11-2/45

Hva er et unntak? Et program må være i stand til å håndtere unormale situasjoner som kan oppstå under utføring. Et unntak (eng. exception) i Java signaliserer en feilsituasjon som oppstår under programutføring. Eksempler på feilsituasjoner: 1. Programmeringsfeil -- oppstår på grunn av logiske feil. Ulovlig indeksering i en tabell. Forsøk på å dividere med 0. Metodekall med ulovlige parametere. Bruk av null-referanse for å aksessere medlemmer i et objekt. 2. Kjørefeil -- som programmet har lite herredømme over. Åpning av fil som ikke eksisterer. Lese- eller skrivefeil ved bruk av fil. En nettforbindelse som går ned. JFPS 11: Unntakshåndtering 11-3/45 Litt om programutføring En programstabel brukes til å håndtere utføring av metoder. Et element (kalt stabelramme) på programstabelen tilsvarer et metodekall. Hvert metodekall fører til at det opprettes en ny stabelramme. Stabelrammen inneholder diverse opplysninger, bl.a. om lagring av lokale variabler. Når metoden er ferdig, fjernes dens ramme. Metoden som har stabelrammen på toppen av programstabelen blir utført. Ved retur fra en metode fortsetter programutføringen i metoden som tilsvarer stabelrammen som nå er blitt avdekket på toppen av programstabelen. Under utføringen vil alle stabelrammer på programstabelen til enhver tid angi hvilke metoder som er aktive, det vil si ikke ferdig utførte. Ved et gitt tidspunkt under utføringen, angir programstabelutlistingen hvilke metoder som er aktive. JFPS 11: Unntakshåndtering 11-4/45

Metodeutføring og unntakspropagering Vi skal bruke følgende problem til å illustrere metodeutføring og unntakspropagering. Beregne hastighet når avstand og tid er gitt. Programmet bruker tre metoder: 1. main() 2. skrivhastighet() 3. beregnhastighet() Merk heltallsdivisjon i beregning av uttrykket (avstand/tid). heltallsdivisjon med 0 er en ulovlig operasjon i Java JFPS 11: Unntakshåndtering 11-5/45 Metodeutføring (Program 11.1) public class Hastighet1 { public static void main(string[] args) { skrivhastighet(100, 20); // (1) System.out.println(""); // (2) private static void skrivhastighet(int kilometer, int timer) { int hastighet = beregnhastighet(kilometer, timer); // (3) System.out.println("Hastighet = " + // (4) kilometer + " / " + timer + " = " + hastighet); System.out.println("Ferdig."); // (5) private static int beregnhastighet(int avstand, int tid) { System.out.println(""); // (6) return avstand/tid; // (7) JFPS 11: Unntakshåndtering 11-6/45

Normal utføring (Figur 11.1)"kast og fang"-prinsippet Hastighet1 System.out main() args = skrivhastighet(100,20) // (1) kilometer = 100 timer = 20 beregnhastighet(100,20) // (3) avstand = 100 tid = 20 println("") // (6) 100/20 5 // (7) hastighet = 5 println("hastighet = 100 / 20 = 5") // (4) println("ferdig.") // (5) println("") // (2) Metodeutføring Utskrift fra programmet: Hastighet = 100 / 20 = 5 Ferdig. JFPS 11: Unntakshåndtering 11-7/45 Et unntak kastes når en feilsituasjon oppstår under programutføring, og fanges av en unntakshåndterer som behandler det. Erstatt i Program 11.1: med skrivhastighet(100, 20); // (1) skrivhastighet(100, 0); // (1) Andre parameter er 0. Utføringen av programmet er illustrert i sekvensdiagrammet i Figur 11.2. I (7) kastes det et ArithmeticException-unntak, som formidles tilbake (propageres) gjennom stabelrammer på programstabelen. JFPS 11: Unntakshåndtering 11-8/45

Unntakspropagering (ved heltallsdivisjon med 0) (Figur 11.2) Hastighet1 System.out main() args = skrivhastighet(100,0) // (1) kilometer = 100 timer = 0 beregnhastighet(100,0) // (3) avstand = 100 tid = 0 println("") // (6) 100/0 unntakpropagering :ArithmeticExeception "/ by zero" Utskrift på terminal: Utskrift fra programmet Utskrift fra standard unntakshåndterer Exception in thread "main" java.lang.arithmeticexception: / by zero at Hastighet1.beregnHastighet(Hastighet1.java:17) at Hastighet1.skrivHastighet(Hastighet1.java:9) at Hastighet1.main(Hastighet1.java:4) klassenavn metodenavn filnavn linjenr. i filen der kallet til neste metode forekommer JFPS 11: Unntakshåndtering 11-9/45 Unntakspropagering Programutføringen fortsetter ikke på normal måte under unntakspropageringen, og unntaket sendes ikke videre med return-setningen. Unntaket tilbys til aktive metoder i tur og orden. Dersom en aktiv metode ikke fanger unntaket, avbrytes utføringen av metoden, m.a.o. fjernes dens stabelramme fra programstabelen. Når unntaket har propagert til "toppnivå", blir det behandlet av en standard unntakshåndterer i Javas virtuelle maskin. Standard unntakshåndtereren genererer en programstabelutlisting på terminalen. JFPS 11: Unntakshåndtering 11-10/45

Unntakshåndtering: try-catch En try-blokk kan inneholde vilkårlig kode, men hensikten er å legge inn setninger som man vet kan lede til at et unntak blir kastet under utføring. En catch-blokk utgjør en unntakshåndterer. En catch-blokk hører sammen med en try-blokk. Et unntak som kan bli kastet som resultat av utføring av koden i try-blokken, kan fanges og behandles i en tilhørende catch-blokk. JFPS 11: Unntakshåndtering 11-11/45 Typiske scenarier ved bruk av try-catch-setning try-blokken inneholder kode som kan føre til at et unntak blir kastet. try-blokk catch-blokk try { int hastighet = beregnhastighet(kilometer, timer); System.out.println("Hastighet = " + kilometer + " / " + timer + " = " + hastighet); catch (ArithmeticException u) { én catch-blokk-parameter System.out.println(u); System.out.println("Unntak behandlet i skrivhastighet()-metoden."); En catch-blokk fanger eventuelt unntak og behandler det dersom det er av riktig type. 1. Koden i try-blokken utføres, og ingen unntak blir kastet. Normalutføring fortsetter etter try-catch-blokkene. 2. Koden i try-blokken utføres, og et unntak blir kastet. Dette unntaket blir fanget og behandlet i en tilhørende catch-blokk. Avbryter utføringen av try-blokken, slik at handlingene i resten av try-blokken ikke blir utført. Normalutføring fortsetter etter try-catch-blokkene. JFPS 11: Unntakshåndtering 11-12/45

3. Koden i try-blokken utføres, og et unntak blir kastet, men ingen catch-blokk blir funnet for å behandle unntaket. Avbryter utføringen av try-blokken, slik at handlingene i resten av try-blokken ikke blir utført. Unntaket blir propagert. try-catch-scenarier (Figur 11.4) Utfør try-blokk [unntak] Finn catch-blokk [ingen catch-blokk funnet] [ingen unntak] 1 2 3 [unntak 1 ] [unntak 2 ] [unntak n ] Utfør catch-blokk for unntak 1 Utfør catch-blokk for unntak 2 Utfør catch-blokk for unntak n Ingen unntak eller unntak behandlet. Normal utføring fortsetter etter try-catch-blokkene. Unntak ikke behandlet. Utføring abortert og unntak propagert. JFPS 11: Unntakshåndtering 11-13/45 try-catch-scenario 1 I Program 11.2 bruker metoden skrivhastighet() en try-catch-setning, (3). Den tilhørende catch-blokken, (6), er deklarert til å fange unntak av typen ArithmeticException. Utføringsmønsteret for Program 11.2 er vist i Figur 11.5. JFPS 11: Unntakshåndtering 11-14/45

Unntakshåndtering (Program 11.2) public class Hastighet2 { public static void main(string[] args) { skrivhastighet(100, 20); // (1) System.out.println(""); // (2) private static void skrivhastighet(int kilometer, int timer) { try { // (3) int hastighet = beregnhastighet(kilometer, timer); // (4) System.out.println("Hastighet = " + // (5) kilometer + " / " + timer + " = " + hastighet); catch (ArithmeticException u) { // (6) System.out.println(u); // (7) System.out.println("Unntak behandlet i skrivhastighet()-metoden."); // (8) System.out.println("Ferdig."); // (9) private static int beregnhastighet(int avstand, int tid) { System.out.println(""); // (10) return avstand/tid; // (11) JFPS 11: Unntakshåndtering 11-15/45 Unntakshåndtering (Figur 11.5) (scenario 1) Hastighet1 System.out main() args = skrivhastighet(100,20) // (1) kilometer = 100 timer = 20 try { beregnhastighet(100,20) // (4) avstand = 100 tid = 20 println("") // (10) 100/20 5 // (11) hastighet = 5 println("hastighet = 100 / 20 = 5") // (5) println("ferdig.") // (9) println("") // (2) Utskrift fra programmet: Hastighet = 100 / 20 = 5 Ferdig. JFPS 11: Unntakshåndtering 11-16/45

Erstatt i Program 11.2: skrivhastighet(100, 20); // (1) med try-catch-scenario 2 skrivhastighet(100, 0); // (1) Andre parameter er 0. Heltallsdivisjon med 0 fører til at et ArithmeticException-unntak blir kastet ved (11) i metoden beregnhastighet(). Utføringen av denne metoden avbrytes, og unntaket propageres. Det blir fanget av catch-blokken i metoden skrivhastighet(). Etter behandlingen av unntaket gjenopprettes normalutføring av programmet. Utskriften viser normalutføring av metoden skrivhastighet() fra dette tidspunktet. JFPS 11: Unntakshåndtering 11-17/45 Unntakshåndtering (Figur 11.6) (scenario 2) Hastighet2 System.out main() args = skrivhastighet(100,0) // (1) kilometer = 100 timer = 0 try { beregnhastighet(100,0) // (4) avstand = 100 tid = 0 println("") // (10) catch() { 100/0 println(u) // (6) :ArithmeticException "/ by zero" println("unntak behandlet i skrivhastighet()-metoden.") // (7) println("ferdig.") // (9) println("") // (2) Utskrift fra programmet: java.lang.arithmeticexception: / by zero Unntak behandlet i skrivhastighet()-metoden. Ferdig. JFPS 11: Unntakshåndtering 11-18/45

try-catch-scenario 3 Scenario 3 belyser hva som skjer når et unntak blir kastet under utføring av en tryblokk og det ikke finnes en tilhørende catch-blokk for å behandle unntaket. Programmets utføringsmønster i Figur 11.7 viser at heltallsdivisjon med 0 igjen fører til at et ArithmeticException-unntak blir kastet ved (15) i metoden beregnhastighet(). Utføringen av denne metoden avbrytes, og unntaket propageres. ArithmeticException-unntaket blir ikke fanget av catch-blokken i metoden skrivhastighet(), siden den fanger unntak av type IllegalArgumentException. Utføringen av metoden skrivhastighet() avbrytes (handling i (13) blir ikke utført), og unntaket propageres videre. Unntaket ArithmeticException blir nå fanget av catch-blokken i metoden main() ved (3). Etter behandlingen av unntaket i catch-blokken i metoden main() gjenopprettes normalutføring av programmet. Utskriften viser normalutføring av metoden main() fra dette tidpunktet. JFPS 11: Unntakshåndtering 11-19/45 Unntakshåndtering (Program 11.3) (scenario 3) public class Hastighet3 { public static void main(string[] args) { try { // (1) skrivhastighet(100, 0); // (2) catch (ArithmeticException u) { // (3) System.out.println(u); // (4) System.out.println("Unntak behandlet i main()-metoden."); // (5) System.out.println(""); // (6) private static void skrivhastighet(int kilometer, int timer) { try { // (7) int hastighet = beregnhastighet(kilometer, timer); // (8) System.out.println("Hastighet = " + // (9) kilometer + " / " + timer + " = " + hastighet); catch (IllegalArgumentException u) { // (10) System.out.println(u); // (11) System.out.println("Unntak behandlet i skrivhastighet()-metoden."); // (12) System.out.println("Ferdig."); // (13) JFPS 11: Unntakshåndtering 11-20/45

private static int beregnhastighet(int avstand, int tid) { System.out.println(""); // (14) return avstand/tid; // (15) JFPS 11: Unntakshåndtering 11-21/45 Unntakshåndtering (Figur 11.7) (scenario 3) Hastighet3 System.out main() args = try { skrivhastighet(100,0) // (1) kilometer = 100 timer = 0 try { beregnhastighet(100,0) // (8) avstand = 100 tid = 0 println("") // (14) 100/0 catch(arithmeticexception u) { println(u) // (4) println("") // (6) :ArithmeticException "/ by zero" println("unntak behandlet i main()-metoden.") // (5) Utskrift fra programmet: java.lang.arithmeticexception: / by zero Unntak behandlet i main()-metoden. JFPS 11: Unntakshåndtering 11-22/45

Utdrag av unntaksklasser (Figur 11.8) java.lang Throwable java.io IOException Exception ClassNotFoundException Error AssertionError EOFException FileNotFoundException RuntimeException NullPointerException ArithmeticException ClassCastException IllegalArgumentException NumberFormatException IndexOutOfBoundsException ArrayIndexOutOfBoundsException StringIndexOutOfBoundsException Skyggelagte klasser (og deres subklasser) representerer ikke-kontrollerte unntak. JFPS 11: Unntakshåndtering 11-23/45 Utdrag av metoder fra Throwable-klassen (Tabell 11.1) Metode String getmessage() void printstacktrace() Beskrivelse Returnerer strengen i unntaket. Strengen angir ytterligere forklaring på unntaket. Skriver på terminalen programstabelutlistingen som førte til at unntaket ble kastet. JFPS 11: Unntakshåndtering 11-24/45

Unntaksklassen Exception og kontrollerte unntak Unntak som tilhører Exception-klassen og dens subklasser, med unntak av subklasser til RuntimeException-klassen, kalles kontrollerte unntak (eng. checked exceptions). Kompilatoren kontrollerer at en metode som kaster et kontrollert unntak, eksplisitt håndterer unntaket (mer om det senere). Unntaksklassen RuntimeException og ikke-kontrollerte unntak Klassen RuntimeException og dens subklasser representerer unntak som angår typiske uforutsette feil, som for eksempel programmeringsfeil. Unntak som er definert ved klassen RuntimeException og dens subklasser kalles ikke-kontrollerte unntak (eng. unchecked exceptions). Det er ikke påkrevet at de fanges, men feilårsaken må rettes opp i programmet. Unntaksklassen Error Subklassen AssertionError brukes til å signalisere at en påstand ikke holder under utføringen. Slike unntak burde ikke fanges. JFPS 11: Unntakshåndtering 11-25/45 Eksplisitt kast av et unntak Et program kan eksplisitt kaste et unntak med throw-setningen: throw new ArithmeticException("Avstand og tid kan ikke være < 0"); Utføring av en throw-setning avbryter normalutføring av programmet, og unntaket propageres på vanlig måte. Det er vanlig å bruke en passende unntaksklasse til å definere en feilsituasjon og gi supplerende opplysninger om unntaket i konstruktørkallet. I Program 11.4 vil programutføringen føre til at et unntak av klassen ArithmeticException blir kastet i metoden beregnhastighet(), (2). Dette unntaket blir propagert og blir fanget av catch-blokken i main()-metoden. Fra dette tidspunktet fortsetter normalutføring av programmet. JFPS 11: Unntakshåndtering 11-26/45

Eksplisitt kast av unntak (Program 11.4) public class Hastighet4 { public static void main(string[] args) { try { skrivhastighet(-100, 10); // (1) Verdi mindre enn 0. catch (ArithmeticException u) { System.out.println(u); System.out.println("Unntak behandlet i main()-metoden."); System.out.println(""); private static void skrivhastighet(int kilometer, int timer) { int hastighet = beregnhastighet(kilometer, timer); System.out.println("Hastighet = " + kilometer + " / " + timer + " = " + hastighet); System.out.println("Ferdig."); private static int beregnhastighet(int avstand, int tid) { System.out.println(""); if (avstand < 0 tid < 0) // (2) throw new ArithmeticException("Avstand og tid kan ikke være < 0"); return avstand/tid; JFPS 11: Unntakshåndtering 11-27/45 Utdata fra programmet: java.lang.arithmeticexception: Avstand og tid kan ikke være < 0 Unntak behandlet i main()-metoden. JFPS 11: Unntakshåndtering 11-28/45

Definere egne unntakstyper Det anbefales å definere nye subklasser til klassen Exception. Dette gjør at nye unntak automatisk blir kontrollert av kompilatoren. class HastighetsBeregningsUnntak extends Exception { // kontrollert unntak HastighetsBeregningsUnntak(String str) { super(str); Det er vanligvis tilstrekkelig å definere en konstruktør som tar en strengparameter. JFPS 11: Unntakshåndtering 11-29/45 Håndtering av flere unntak Dersom koden i en try-blokk kan kaste forskjellige typer unntak, kan man spesifisere én catch-blokk for hver type unntak etter try-blokken (Program 11.5). Indeksering i strengtabellen args, (3) og (4), kan kaste et ikke-kontrollert ArrayIndexOutOfBoundsException-unntak med mindre minst to strenger er spesifisert på kommandolinjen. Konvertering til heltall med parseint()-metoden, (3) og (4), kan kaste et ikkekontrollert NumberFormatException-unntak dersom noen av strengene inneholder tegn som ikke kan inngå i et heltall. JFPS 11: Unntakshåndtering 11-30/45

try-blokk med flere catch-blokker (Progam 11.5) public class Hastighet5 { public static void main(string[] args) { int arg1, arg2; // (1) try { // (2) arg1 = Integer.parseInt(args[0]); // (3) arg2 = Integer.parseInt(args[1]); // (4) catch (ArrayIndexOutOfBoundsException unntak) { // (5) System.out.println("Angi både kilometer og timer."); System.out.println("Bruk: java Hastighet5 <kilometer> <timer>"); return; catch (NumberFormatException unntak) { // (6) System.out.println("Kilometer og timer må være heltall."); System.out.println("Bruk: java Hastighet5 <kilometer> <timer>"); return; skrivhastighet(arg1, arg2); // (7) System.out.println(""); JFPS 11: Unntakshåndtering 11-31/45 private static void skrivhastighet(int kilometer, int timer) { try { int hastighet = beregnhastighet(kilometer, timer); System.out.println("Hastighet = " + kilometer + " / " + timer + " = " + hastighet); catch (ArithmeticException u) { System.out.println(u); System.out.println("Unntak behandlet i skrivhastighet()-metoden."); System.out.println("Ferdig."); private static int beregnhastighet(int avstand, int tid) { System.out.println(""); if (avstand < 0 tid < 0) throw new ArithmeticException("Avstand og tid kan ikke være < 0"); return avstand/tid; JFPS 11: Unntakshåndtering 11-32/45

Utdata fra programmet: >java Hastighet5 100 Angi både kilometer og timer. Bruk: java Hastighet5 <kilometer> <timer> >java Hastighet5 200 4u Kilometer og timer må være heltall. Bruk: java Hastighet5 <kilometer> <timer> >java Hastighet5 200-10 java.lang.arithmeticexception: Avstand og tid kan ikke være < 0 Unntak behandlet i skrivhastighet()-metoden. Ferdig. >java Hastighet5 200 0 java.lang.arithmeticexception: / by zero Unntak behandlet i skrivhastighet()-metoden. Ferdig. >java Hastighet5 100 20 Hastighet = 100 / 20 = 5 Ferdig. JFPS 11: Unntakshåndtering 11-33/45 Typiske programmeringsfeil ved unntakshåndtering En parametertype i én catch-blokk kan skygge for andre unntakstyper i etterfølgende catch-blokker. For eksempel skygger superklassen RuntimeException i catch-blokk (1) for subklassen ArithmeticException i catch-blokk (2): try { catch (RuntimeException unntak1) { // (1) catch (ArithmeticException unntak2) { // (2) Unntak av typen ArithmeticException blir fanget av catch-blokk (1) og aldri av catch-blokk (2), siden objekter av subklasser kan tilordnes en superklassereferanse. Kompilatoren vil varsle dersom slike tilfeller forekommer. Ikke fang alle unntak i én catch-blokk ved å bruke mer generelle unntaksklasser, for eksempel Exception og RuntimeException. Bruk av spesifikke unntaksklasser, gjerne med flere catch-blokker, anbefales i trycatch-konstruksjonen for å øke programforståelsen. JFPS 11: Unntakshåndtering 11-34/45

Håndtering av kontrollerte unntak Hensikten med unntakshåndteringen er å behandle unormale situasjoner under programutføring. Det er mulig for en metode som kaster et unntak, å la unntaket propagere videre uten å gjøre noe med det. Dette oppfordrer til utvikling av lite robuste programmer. Bruk av kontrollerte unntak gir en strategi der en metode som kan kaste et slikt unntak, tvinges til å ta stilling til hvordan unntaket skal håndteres: 1. Fange og behandle unntaket i en try-catch-setning. 2. Tillate videre propagering av unntaket med en throws-klausul spesifisert i metodedeklarasjonen. En throws-klausul spesifiseres i metodehodet, mellom parameterlisten og metodekroppen: metodenavn () throws unntaksklasse 1,, unntaksklasse n { Siden kompilatoren unnlater å sjekke ikke-kontrollerte unntak og metodene kan la være å håndtere dem, spesifiseres vanligvis ikke slike unntak i en throws-klausul. JFPS 11: Unntakshåndtering 11-35/45 Håndtering av kontrollerte unntak Gitt at metode foo() kaller metode bar(): void bar() throws K { /**/ void foo() { bar(); Løsning: Enten void foo() throws K { bar(); eller: // K er kontrollert unntak. // Ikke godtatt av kompilatoren. // Kaster unntaket videre. void foo() { try { bar(); catch(k k) {k.printstacktrace() // Fanger og behandler unntaket. Kompilatoren vil sjekke at en metode som kan kaste et kontrollert unntak oppfyller et av kravene ovenfor. Dette betyr at enhver klient av en metode som kan propagere et kontrollert unntak i en throws-klausul, må ta stilling til hvordan dette unntaket skal håndteres. Dersom et kontrollert unntak spesifisert i en throws-klausul blir propagert helt til toppnivået, vil det bli behandlet av en standard unntakshåndterer på vanlig måte. JFPS 11: Unntakshåndtering 11-36/45

Eksempel: kontrollerte unntak I Program 11.6 definerer klassen HastighetsBeregningsUnntak kontrollerte unntak, siden den er en subklasse av klassen Exception. Metoden beregnhastighet() kaster et unntak av typen HastighetsBeregningsUnntak i en if-setning, (5). Den velger å kaste dette unntaket videre i en throws-klausul, (4). Metoden skrivhastighet() som kaller metoden beregnhastighet(), velger også å kaste det videre i en throws-klausul, (3). Metoden main() som kaller metoden skrivhastighet(), velger å fange og behandle dette unntaket i en try-catch-blokk, (1) og (2). Forsøk på å utelate throws-klausulene vil resultere i kompileringsfeil. JFPS 11: Unntakshåndtering 11-37/45 Håndtering av kontrollerte unntak (Program 11.6) public class Hastighet6 { public static void main(string[] args) { int arg1, arg2; try { arg1 = Integer.parseInt(args[0]); arg2 = Integer.parseInt(args[1]); catch (ArrayIndexOutOfBoundsException unntak) { System.out.println("Angi både kilometer og timer."); System.out.println("Bruk: java Hastighet6 <kilometer> <timer>"); return; catch (NumberFormatException unntak) { System.out.println("Kilometer og timer må være heltall."); System.out.println("Bruk: java Hastighet6 <kilometer> <timer>"); return; try { //(1) skrivhastighet(arg1, arg2); catch (HastighetsBeregningsUnntak unntak) { //(2) System.out.println(unntak); System.out.println(""); JFPS 11: Unntakshåndtering 11-38/45

private static void skrivhastighet(int kilometer, int timer) throws HastighetsBeregningsUnntak { //(3) int hastighet = beregnhastighet(kilometer, timer); System.out.println("Hastighet = " + kilometer + " / " + timer + " = " + hastighet); System.out.println("Ferdig."); private static int beregnhastighet(int avstand, int tid) throws HastighetsBeregningsUnntak { //(4) System.out.println(""); if (avstand < 0 tid <= 0) //(5) throw new HastighetsBeregningsUnntak("Avstand og tid må være > 0"); return avstand/tid; JFPS 11: Unntakshåndtering 11-39/45 class HastighetsBeregningsUnntak extends Exception { HastighetsBeregningsUnntak(String str) { super(str); Utdata fra programmet: >java Hastighet6 100 0 HastighetsBeregningsUnntak: Avstand og tid må være > 0 >java Hastighet6-200 10 HastighetsBeregningsUnntak: Avstand og tid må være > 0 >java Hastighet6 200 10 Hastighet = 200 / 10 = 20 Ferdig. JFPS 11: Unntakshåndtering 11-40/45

Utføring av finally-blokk En finally-blokk kan forekomme sammen med en try-blokk. En catch-block trenger ikke nødvendigvis å være spesifisert. Koden i finally-blokken blir alltid utført dersom try-blokken blir utført. Det spiller ingen rolle om et unntak ble kastet eller ikke. "Oppryddingskode" kan legges i en finally-blokk slik at den alltid blir utført. Klassen Hastighet7 illustrerer utføring av finally-blokk. En finally-blokk er spesifisert ved (13), med tilhørende try-blokk ved (7). Utskriften viser at koden i finally-blokken blir utført uansett. public class Hastighet7 { public static void main(string[] args) { try { // (1) skrivhastighet(100, 20); // (2a) // skrivhastighet(100, 0); // (2b) catch (ArithmeticException u) { // (3) System.out.println(u); // (4) System.out.println("Unntak behandlet i main()-metoden."); // (5) System.out.println(""); // (6) JFPS 11: Unntakshåndtering 11-41/45 private static void skrivhastighet(int kilometer, int timer) { try { // (7) int hastighet = beregnhastighet(kilometer, timer); // (8) System.out.println("Hastighet = " + // (9) kilometer + " / " + timer + " = " + hastighet); catch (IllegalArgumentException u) { // (10) System.out.println(u); // (11) System.out.println("Unntak behandlet i skrivhastighet()-metoden."); // (12) finally { // (13) System.out.println("finally-blokk utført."); // (14) System.out.println("Ferdig."); // (15) private static int beregnhastighet(int avstand, int tid) { System.out.println(""); // (16) return avstand/tid; // (17) JFPS 11: Unntakshåndtering 11-42/45

Utføring med kodelinjen: skrivhastighet(100, 20); gir følgende utskrift: Hastighet = 100 / 20 = 5 finally-blokk utført. Ferdig. Utføring med kodelinjen: skrivhastighet(100, 0); // (2a) // (2b) gir følgende utskrift: finally-blokk utført. java.lang.arithmeticexception: / by zero Unntak behandlet i main()-metoden. Legg merke til at utføringen av metoden skrivhastighet() ble avbrutt etter at finally-blokken var utført. JFPS 11: Unntakshåndtering 11-43/45 Unntakskasting og arv En overkjørt metode i subklassen har bare lov å spesifisere i sin throws-klausul en undermengde av unntak fra throws-klausul i metodedefinisjonen fra superklassen. // Klasse A public void enmetodemedmangeunntak() throws Unntak1, Unntak2, Unntak3 { // I subklassen B som er utledet fra superklassen A public void enmetodemedmangeunntak() throws Unntak1, Unntak3 { JFPS 11: Unntakshåndtering 11-44/45

Oppsummering av unntakshåndtering "Kast og fang "-regel for kontrollerte unntak: En metode kan fange unntak den kaster og behandle dem i catch-blokker. De kontrollerte unntakene som en metode kan kaste og ikke fanger, må deklareres i en throws-klausul til metoden. En metode kan eksplisitt kaste et unntak v.h.a. throw-setningen. enmetode() throws Unntak 1, Unntak 2,, Unntak n { try { // handlinger som kan føre til at et av følgende unntak kan kastes: // Unntak 1, Unntak 2,, Unntak n og Unntak a,, Unntak m throw new Unntak i (); // kaster et unntak av typen Unntak i catch (Unntak j u j ) { // behandler unntak av typen Unntak j // kode for å behandle unntak u j catch (Unntak k u k ) { // behandler unntak av typen Unntak k // kode for å behandle unntak u k finally { // Koden som alltid blir utført dersom try blir utført. try-catch-finally blokk JFPS 11: Unntakshåndtering 11-45/45