Förra gången Recursive Descent/Rekursiv nedgång Stokenizer Introduktion till OU3 (24 april 2015 F7.1 ) Dagens agenda En demonstration av Stokenizer Fel i program Felhantering med undantag Egna undantag Avbildningar (Map) (24 april 2015 F7.2 ) Stokenizer: Metoder int nextToken() boolean isNumber() boolean isWord() boolean isEOL() boolean isEOS() double getNumber() String getWord() int getChar() String toString() String getToken() String getPreviousToken() Stegar fram till n?sta tok True om aktuell tok ?r ett tal True om aktuell tok ?r ett ord True om aktuell tok ?r ett radslut True om aktuell tok ?r str?mslut Returnerar aktuellt tal. Fel om ej tal Returnerar aktuellt ord. Fel om ej ord. Returnerar aktuellt tecken. Aktuell tok som med diverse information Returnerar aktuell tok som str?ng Returnerar f?reg?ende tok som str?ng (24 april 2015 F7.3 ) Fel i program När man skriver och kör ett datorprogram är det mycket som kan gå fel. Man kan klassicera felen i några olika kategorier: I Kompileringsfel. Brott mot Javas syntax och semantikregler. int a + 5; eller int a = 5; int[] b = a; I Exekveringsfel. Fel som uppstår vid körning av programmet. Upptäcks och hanteras antingen av JVM eller den egna koden. Ex: int[] a = new int[2]; a[-1] = 5; kommer kasta ett undantag av typen ArrayIndexOutOfBoundsException. (24 april 2015 F7.4 ) Fel i program, forts... I Felaktiga resultat. Exempel harmonic från rekursionsuppgiften: Här i iterativ form. public static double harmonic(int n) { assert n >= 0; double sum = 0.0; while(n > 0) { sum += 1/n; n = n - 1; } return sum; } vilket alltid ger resultatet 1 om man skickar 1 eller större som argument. Felaktiga resultat upptäcks vid testning, ute i det fria eller inte alls. (24 april 2015 F7.5 ) Ett sätt att hantera exekveringsfel: Undantag/Exceptions Ett undantag är ett objekt av en klass som ärver (extends) från Exception, eller vanligare i praktiken, från RuntimeException. Denna klass kan innehålla utförlig information om felet eller bara låta dess namn tala om vilket fel som har uppstått. ArrayIndexOutOfBoundsException programmet försökte komma åt. NullPointerException innehåller information om vilket index däremot innehåller ingen utförligare information. (24 april 2015 F7.6 ) Kastande och fångande När ett fel upptäcks av Javamaskinen så kastas ett undantag. Detta kan även göras från den egna koden med throw new WithdrawalFailedBankIsBrokeException(); t.ex om programmet är en bankapplikation. throw är nyckelordet i Java som kastar undantaget. Fångar undantagen. Kan användas både för att hantera felet och fortsätta körningen eller reagera på felet och sen kasta vidare det. Man kan associera era catch med en try om man vill reagera olika på olika fel. catch Anger att en viss bit kod kommer utföras efter try/catch satserna oavsett om undantaget sedan kastas vidare. finally (24 april 2015 F7.7 ) Ett exempel try { System.out.println(This will be printed for sure!); throw new IOException(); System.out.println(Ain't gonna happen!); } catch(IOException e) { System.out.println(Good catch mademoiselle!); throw e; //Pass it on } catch(InterruptedException ie) { throw ie; } finally { System.out.println(This will always be printed. Yes!); } //Won't print unless `throw e;' is removed System.out.println(The exception was handled locally.); (24 april 2015 F7.8 ) Vad händer när ett undantag kastas? När ett undantag kastas med t.ex. throw SuspiciousException(); och det inte nns någon matchande catch(SuspiciousException e) i den aktuella metoden så avbryts den och inget värde returneras. Detsamma händer i den anropande metoden, våning för våning, tills dess att någon fångar undantaget. Om ingen har fångat undantaget när det når till Javamaskinen avbryts programmet med en felutskrift. Detta är något som är användbart som felsökningshjälp men ingenting man någonsin vill att en användare av sitt program ska se. (24 april 2015 F7.9 ) Checked/Unchecked Exceptions //A method that can throw a checked exception public void sleepyMethod(int seconds) throws InterruptedException { Thread.sleep(1000 * seconds); System.out.println(Sleep break over. Back to coding!); } Alla klasser av undantag som ärver från RuntimeException är unchecked. Man behöver alltså inte deklarera i en metods huvud att ett sådant undantag kan kastas. Alla andra är checked och måste deklareras med throws. (24 april 2015 F7.10 ) Diagram över undantagsklassernas hierarki Exception RuntimeException InterruptedException NullPointerException ArrayIndexOutOfBounds... IOException FileNotFoundException EOFException IllegalArgumentException (24 april 2015 F7.11 ) Varning! Varning! Man ska aldrig någonsin skriva en undantagshanterare som fångar Exception eller RuntimeException. Eftersom rena programmeringsfel som ArrayIndexOutOfBoundsException och NullPointerException ärver från RuntimeException så göms dessa och får programmet att helt enkelt bete sig konstigt. Man har alltså bytt ett exekveringsfel mot ett felaktigt resultat, vilket man aldrig vill göra. (24 april 2015 F7.12 ) Skapa egna undantag Enklast är att skapa ett undantag som inte gör något speciellt utan som bara tar emot ett felmeddelande och vidarebefordrar det till basklassen. Så här kan det se ut: public class SimpleException extends RuntimeException { public SimpleException(String msg) { super(msg); } } Sen kan det kastas med: throw new SimpleException(Bad things can happen to anyone.); (24 april 2015 F7.13 ) Map/Avbildning Ofta vill man kunna associera någon form av data med någon annan, t.ex. namn med telefonnummer och eektivt kunna kolla upp telefonnummret om man anger namnet. Då vill man använda det som kallas en associativ datastruktur. Namnet kommer av att man associerar ett värde från en denitionsmängd med ett värde ur en värdemängd. Exempel: Matematiska funktioner Array (Heltal -> Värde) I OU3: Variabellista (Sträng -> Double) (24 april 2015 F7.14 ) Map i Java Java har inbyggda klasser för eektiva avbildningar: TreeMap och HashMap. Dessa implementerar båda interfacet Map. TreeMap, HashMap och Map måste importeras från paketet java.util. (24 april 2015 F7.15 ) De viktigaste metoderna i Map Tömmer mappen void clear() Lägger till ett element i mappen void put(K key, V value) Hämtar det värde i mappen förknippat med key V get(K key) Kollar om ett element nns boolean containsKey(K key) Gör om mappens innehåll till en sträng String toString() (24 april 2015 F7.16 ) Nästa gång Nästa gång kommer vi behandla en rekursiv datastruktur: Den länkade listan. OU4 kommer handla i det närmaste uteslutande om rekursiva datastrukturer och tillhörande algoritmer. (24 april 2015 F7.17 )