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 )