1. Unntak
>
Endelig tenkte programmerere å standardisere og automatisere feilhåndtering. Dette skjedde da unntak ble oppfunnet. Nå håndterer unntaksmekanismen 80 % av eksepsjonelle situasjoner.
Hvis noen forskere kom med unntak, var det sannsynligvis temaet for doktoravhandlingen hans eller hennes. Hvis en programmerer kom på det, så kan han ha fått et vennlig klapp på skulderen fra en kollega: "Ser greit ut, bro."
Når det oppstår en feil i et Java-program, for eksempel divisjon med 0
, skjer det noen fantastiske ting:
Steg en
Det opprettes et spesielt unntaksobjekt som inneholder informasjon om feilen som oppstod.
Alt i Java er et objekt, og unntak er ingen unntak 🙂 Unntaksobjekter har sine egne klasser, og det eneste som skiller dem fra vanlige klasser er at de arver klassen Throwable
.
Trinn to
Unntaksobjektet er "kastet". Kanskje ordlyden her kunne vært bedre. «Å kaste et unntak» er mer som å utløse en brannalarm eller gi et «DEFCON 1»-varsel.
Når et unntak blir kastet til Java-maskinen, stopper normal drift av programmet og "nødprotokoller" begynner.
Trinn tre
Metoden der unntaket ble kastet, avsluttes umiddelbart. Unntaket overføres til anropsmetoden, som også avsluttes umiddelbart. Og så videre nedover kjeden til main
metoden går ut. Når main
metoden avsluttes, gjør programmet det også.
Eksempel:
Kode | Konsollutgang |
---|---|
|
|
Et unntak oppstår på linje 20: divisjon med 0. Java-maskinen oppretter umiddelbart et unntak — et ArithmeticException
objekt og "kaster" det til metoden.
Metoden divide()
avsluttes umiddelbart, så vi ser aldri strengen: Ingenting forferdelig skjedde: 0. Programmet går tilbake til metoden endTheWorld()
, og situasjonen gjentar seg: det er et ubehandlet unntak i systemet, som gjør at metoden endTheWorld()
også avsluttes unormalt. Deretter main
avsluttes metoden, og programmet stopper.
Hva er hensikten med disse unntakene? Vel, du kan skrive din egen kode for å fange opp spesielle typer unntak og skrive din egen logikk for å håndtere eksepsjonelle situasjoner.
2. Fange-unntak:try-catch
Java har en unntaksfangstmekanisme som lar deg stoppe denne unormale avslutningen av metoder. Det ser slik ut:
try
{
// Code where an exception might occur
}
catch(ExceptionType name)
{
// Exception handling code
}
Denne konstruksjonen kalles en try-catch
blokk.
Koden der unntak kan forekomme er pakket inn i krøllete klammeparenteser, foran ordet try
.
Etter de krøllete klammeparentesene har vi nøkkelordet catch
og, innenfor parentes, deklarasjonen av en unntaksvariabel . Dette etterfølges av krøllete klammeparenteser som omslutter koden som skal kjøres hvis et unntak av den angitte typen inntreffer .
Hvis ingen unntak blir kastet under kjøring av " primærkoden ", vil ikke koden inne i catch-blokken bli utført. Hvis et unntak oppstår, vil det være det (hvis typen av det kastede unntaket er den samme som typen til variabelen i parentes).
Eksempel:
Kode | Konsollutgang |
---|---|
|
|
3. Flere catch
blokker
I teorien kan alle slags unntak kastes i en kodeblokk. Noen vil du ønske å håndtere på en måte, andre på en annen måte, og atter andre vil du bestemme deg for ikke å håndtere i det hele tatt.
Java-utviklere bestemte seg for å hjelpe deg og la deg skrive ikke én, men mange catch
blokker etter try
blokkeringen.
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
}
Eksempel:
Kode | Konsollutgang |
---|---|
|
|
4. Rekkefølge av catch
blokker
Unntak som forekommer i en try
blokk kan bare fanges opp av en enkelt catch
blokk. Du kan ikke ha en unntakshåndteringssituasjon der koden fra flere catch
blokker blir utført.
Men rekkefølgen på blokkene betyr noe.
Du kan ha en situasjon der et unntak kan bli fanget opp av flere blokker. Hvis det er tilfelle, vil unntaket bli fanget opp av den fangblokken som kommer først (nærmest try
blokken).
Hvordan kan du ha en situasjon der flere fangstblokker kan fange det samme unntaket?
Alle unntak tilhører et enkelt arvehierarki - se diagrammet.
Et ArithmeticException
objekt kan tilordnes til en variabel hvis type er ArithmeticException
eller en av dens stamfarklasser: RuntimeException
, Exception
og Throwable
— se diagrammet.
Vi snakker mer om arv og forfedreklasser på nivå 21.
Denne koden vil kompilere helt fint:
Fordeler med arv: |
---|
|
Så du kan fange en ArithmeticException
med hvilken som helst av de 4 catch
blokkene ovenfor.
Eksempel 1:
Kode | Konsollutgang |
---|---|
|
|
I dette eksemplet ArithmeticException
kan den fanges opp av både blokkene catch (Exception e)
og catch (ArithmeticException e)
. Den vil bli fanget opp av blokken nærmest blokken try
- den første catch
blokken.
For å unngå overraskelser, er det best å plassere catch
blokker som kan fange nesten alle unntak nær slutten av listen over catch
blokker.
Typen Throwable
er generelt i stand til å fange opp alle mulige unntak i Java . Hvis du legger den i den første catch
blokken, vil ikke koden kompilere, siden kompilatoren vet at det er uoppnåelige kodeblokker.
GO TO FULL VERSION