Throws och lite Try/Catch
Hej.
Jag förstår inte helt hur en throws sats fungerar i Java. Jag vet hur man använder try och catch. Hittar inga bra förklaringar på engelska som jag orkar läsa igenom, försöker hitta hjälp här.
Det jag förstår av en throws sats är att den gör sig av med felsignaler (Exceptions). Men att man även måste ha med åtminstonde en catch sats om man ska ha en throws. Något sånt.
Jag tycker det är bra om du orkar ta dig igenom en korrekt och fullständig beskrivning på engelska. Så mycket i datorbranschen är bara beskrivet ordentligt på engelska, även om det finns bra förenklade framställningar på svenska, det gäller bara att hitta dessa.
Men jag ska förklara. När ett fel inträffar under körning, t.ex. division med noll, så hanteras det genom en exception (jag skriver ohämmat engelska ord på svenska här). Exceptionet "kastas" (jag använder svenska här), dvs. "throw". Detta har till följd att exekveringen inte fortsätter på nästa rad, utan man lämnar metoden man är i, lämnar metoden som anropade den metoden, osv. och hamnar till slut i Main, och sen kraschar programmet och talar om att man delade med noll.
Om man vill hejda den kedjan av kastningar stoppar man in metodanropet (eller koden som delade med noll) i en try. Då kommer man inte att kastas ända upp till Main, utan till catch som hör till try. Om det står där att man ska fånga division med noll så stannar man där, kör den koden, och fortsätter sen efter den try-satsen. Om det står att man ska fånga några exceptions men inte division med noll, så kastas man vidare.
Man kan som programmerare använda egna exceptions. Man skapar dem som vanligt, tror jag, med new Exception, och man kan definiera egna exceptionklasser som är underklasser till Exception. För att kasta ett sådant exception (vilket man gör t.ex. för att en situation har uppstått som man inte vill eller kan hantera i metoden man är i) använder man throw.
I Java är det så att om en metod kan kasta en viss Exception, så måste det deklareras i raden som inleder metoden: "int handlesomething(int x) throws MyException" eller något sånt. Om en metod som anropar denna metod inte fångar denna exception så måste den själv deklarera detta på samma sätt.
I andra språk som har nån variant av try/catch, t.ex. Python, så behöver man inte deklarera detta.
Först och främst, det är skillnad på throw och throws. Det throw gör är att skapa en ny felsignal (ett Exception), vilket avslutar den nuvarande metoden och skickar signalen till föräldermetoden. Det throws gör är egentligen bara att berätta att en metod, på något sätt, kan ge en viss Exception. Titta exempelvis på följande kod:
Här kommer metoden test alltid att skapa ett RuntimeException med satsen "throw new RuntimeException()". Det avbryter metoden och skickar tillbaka felsignalen till main. Main upptäcker att det har blivit ett fel inuti try-blocket, och går därmed direkt till catch. Catch skriver ut ett felmeddelande och en s.k. stack trace för att hjälpa dig att hitta felet. Det ger följande utskrift:
Man behöver inte nödvändigtvis placera en metod som skapar ett exception inuti ett try...catch-block, utan det beror på vilket exception som skapas. I Java finns två typer av exceptions: check exceptions och unchecked exceptions. Det förstnämnda måste alltid hanteras, antingen genom att placeras inuti try...catch, eller genom att skicka upp det till förälderprocessen (och då måste throws finnas angivet för metoden, till exempel som det gör för metoden test i mitt exempel ovan). unchecked exceptions måste inte nödvändigtvis hanteras på något av de sätten, men det kan vara god vana att göra det ändå. Vill du läsa på mer om det finns t.ex. den här sidan, eller den här frågan på StackOverflow, eller så kan du helt enkelt googla själv.
RuntimeException är ett exempel på ett unchecked exception, och därför behövde jag i min kod inte ha throws eller try...catch - men det betyder inte att det är fel att ha det ändå.
Sen vill jag bara tillägga att kodexemplet jag gav kanske inte ger en bra bild av när man vill använda exceptions (det är ganska meningslöst med en funktion som alltid ger exceptions, oavsett vad). Ofta skapar man ett exception om någonting går snett på vägen, och följande kod kanske ger en bättre bild av hur man till exempel skulle kunna använda dem:
Där metoden skapar ett exception om man till exempel försöker komma åt en position som inte existerar på en karta, eller försöker flytta en enhet till en position den inte kan flyttas till.
Tegelhus skrev:
Tack båda två för hjälpen.