1. Undantag
>
Äntligen tänkte programmerare att standardisera och automatisera felhantering. Detta hände när undantag uppfanns. Nu hanterar undantagsmekanismen 80 % av exceptionella situationer.
Om någon forskare kom med undantag var det troligen ämnet för hans eller hennes doktorsavhandling. Om en programmerare kom på det, så kan han ha fått en vänlig klapp på axeln från en kollega: "Det verkar okej, bro."
När ett fel uppstår i ett Java-program, till exempel division med , 0
händer några underbara saker:
Steg ett
Ett speciellt undantagsobjekt skapas som innehåller information om felet som uppstod.
Allt i Java är ett objekt, och undantag är inga undantag 🙂 Undantagsobjekt har sina egna klasser, och det enda som skiljer dem från vanliga klasser är att de ärver klassen Throwable
.
Steg två
Undantagsobjektet är "kastat". Kanske kan formuleringen här vara bättre. "Att kasta ett undantag" är mer som att utlösa ett brandlarm eller ljuda en "DEFCON 1"-larm.
När ett undantag kastas till Java-maskinen, stoppas den normala driften av programmet och "nödprotokoll" börjar.
Steg tre
Metoden där undantaget kastades avslutas omedelbart. Undantaget överförs till anropsmetoden, som också avslutas omedelbart. Och så vidare i kedjan tills main
metoden går ut. När main
metoden avslutas gör programmet det också.
Exempel:
Koda | Konsolutgång |
---|---|
|
|
Ett undantag inträffar på rad 20: division med 0. Java-maskinen skapar omedelbart ett undantag — ett ArithmeticException
objekt och "kastar" det till metoden.
Metoden divide()
slutar omedelbart, så vi ser aldrig strängen: Inget hemskt hände: 0. Programmet återgår till metoden, endTheWorld()
och situationen upprepar sig: det finns ett ohanterat undantag i systemet, vilket gör att metoden endTheWorld()
också avslutas onormalt. Sedan main
avslutas metoden och programmet stoppas.
Vad är syftet med dessa undantag? Tja, du kan skriva din egen kod för att fånga vissa typer av undantag och skriva din egen logik för att hantera exceptionella situationer.
2. Fånga undantag:try-catch
Java har en undantagsfångningsmekanism som låter dig stoppa denna onormala avslutning av metoder. Det ser ut så här:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Denna konstruktion kallas ett try-catch
block.
Koden där undantag kan förekomma är inlindad i hängslen, föregås av ordet try
.
Efter de lockiga klammerparenteserna har vi catch
nyckelordet och, inom parentes, deklarationen av en undantagsvariabel . Detta följs av klammerparenteser som omsluter koden som ska köras om ett undantag av den angivna typen inträffar .
Om inga undantag slängs under exekvering av den " primära koden ", kommer koden inuti fångstblocket inte att exekveras. Om ett undantag inträffar, kommer det att vara det (om typen av det kastade undantaget är samma som typen av variabeln inom parentes).
Exempel:
Koda | Konsolutgång |
---|---|
|
|
3. Flera catch
block
I teorin kan alla möjliga undantag kastas i ett kodblock. Vissa kommer du att vilja hantera på ett sätt, andra på ett annat sätt, och andra kommer du att bestämma dig för att inte hantera alls.
Java-utvecklare bestämde sig för att hjälpa dig och låta dig skriva inte ett utan många catch
block efter try
blocket.
try
{
// Code where an exception might occur
}
catch (ExceptionType1 name1)
{
// Code for handling ExceptionType1
}
catch (ExceptionType2 name2)
{
// Code for handling ExceptionType2
}
catch (ExceptionType3 name3)
{
// Code for handling ExceptionType3
}
Exempel:
Koda | Konsolutgång |
---|---|
|
|
4. Ordning av catch
block
Undantag som förekommer i ett try
block kan bara fångas upp av ett enda catch
block. Du kan inte ha en undantagshanteringssituation där koden från flera catch
block exekveras.
Men ordningen på blocken spelar roll.
Du kan ha en situation där ett undantag kan fångas upp av flera block. Om så är fallet kommer undantaget att fångas upp av det fångstblock som kommer först (närmast blocket) try
.
Hur kan du ha en situation där flera fångstblock kan fånga samma undantag?
Alla undantag hör till en enda arvshierarki — se diagrammet.
Ett ArithmeticException
objekt kan tilldelas en variabel vars typ är ArithmeticException
eller någon av dess förfaderklasser: , RuntimeException
och Exception
— Throwable
se diagrammet.
Vi kommer att prata mer om arv och förfaderklasser på nivå 21.
Den här koden kommer att kompileras bra:
Fördelar med arv: |
---|
|
Så du kan fånga en ArithmeticException
med något av de 4 catch
blocken ovan.
Exempel 1:
Koda | Konsolutgång |
---|---|
|
|
I det här exemplet ArithmeticException
kan den fångas av både blocken catch (Exception e)
och . catch (ArithmeticException e)
Det kommer att fångas av blocket närmast blocket try
- det första catch
blocket.
För att undvika överraskningar är det bäst att placera catch
block som kan fånga nästan alla undantag nära slutet av listan med catch
block.
Typen Throwable
är i allmänhet kapabel att fånga alla möjliga undantag i Java . Om du lägger den i det första catch
blocket kommer koden inte att kompileras, eftersom kompilatorn vet att det finns oåtkomliga kodblock.
GO TO FULL VERSION