"Hei, Amigo. Vi skal ha en veldig interessant leksjon i dag. Jeg skal fortelle deg om unntak. Unntak er en spesiell mekanisme som lar oss håndtere feil i programmet. Her er noen eksempler på feil som kan oppstå i et program:

1. Programmet kan prøve å skrive en fil når harddisken er helt full.

2. Programmet kan prøve å kalle en metode på en variabel som lagrer en nullreferanse.

3. Programmet kan prøve å dele et tall med 0."

Alle disse handlingene resulterer i feil. Vanligvis er resultatet at programmet avsluttes umiddelbart, siden det ikke gir mening å fortsette å kjøre kode i dette tilfellet.

"Hvorfor?"

"Gjør det mening å fortsette å snu et hjul hvis bilen har kjørt av veien og faller ned fra en klippe?"

"Skal programmet slutte å kjøre, da?"

"Ja. Dette er i hvert fall det som pleide å skje. Enhver feil førte til at programmet avsluttet."

"Det er en veldig smart tilnærming."

"Men ville det ikke vært bedre å prøve å fortsette å kjøre programmet?"

"Ja. Tenk deg at du skrev inn en enorm mengde tekst i Word og lagret den. Hva om lagringsoperasjonen mislykkes, men programmet får deg til å tro at alt er bra? Og du fortsetter å skrive. Det ville være dumt, ikke den?"

"Japp."

"Så kom programmerere med en interessant løsning: hver funksjon ville returnere statusen til arbeidet sitt. 0 betydde at den fungerte som forventet. Enhver annen verdi ville bety at det oppsto en feil, og returverdien var en feilkode."

"Men den tilnærmingen har også sine mangler. Etter hvert (!) funksjonskall må du sjekke returkoden (nummeret). For det første er dette upraktisk: feilhåndteringskoden blir sjelden utført, men må inkluderes overalt. For det andre returnerer funksjoner ofte forskjellige verdier – hva skal du gjøre med dem?"

"Riktig. Jeg tenkte på det også."

"Så kom en lys fremtid i form av unntak og en feilhåndteringsmekanisme. Slik fungerer det:

1. Når det oppstår en feil, oppretter Java Machine et spesielt objekt – et unntak – der den lagrer all feilinformasjon. Det er forskjellige unntak for forskjellige feil.

2. Et unntak fører til at programmet umiddelbart avslutter gjeldende funksjon, og neste funksjon, og så videre – til det avslutter hovedmetoden. Da avsluttes programmet. Programmerere kan også si at Java-maskinen 'løser opp samtalestakken'."

"Men du sa at programmet ikke alltid avsluttes."

"Ja, fordi det er en måte å fange et unntak på. Vi kan skrive spesialkode på rett sted for å fange opp unntakene vi bryr oss om og gjøre noe med dem. Dette er viktige greier."

"For å hjelpe oss med dette er det en spesiell try-catch -konstruksjon. Slik fungerer det:"

Eksempel på et program som fanger opp et unntak (divisjon på 0) og fortsetter å fungere.
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never be shown");
        }
        catch (Exception e)
        {
           System.out.println("Exception has been caught");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}
Skjermutgang:

Program starts
Before method1 calling
Exception has been caught
Program is still running

"Men hvorfor vises ikke 'Etter anropsmetode1. Dette vil aldri bli vist' på skjermen?"

"Jeg er glad du spurte. I linje 25 deler vi med 0, noe som fører til en feil – et unntak. Java-maskinen lager et ArithmeticException -objekt med informasjon om feilen. Objektet er unntaket."

"Unntaket forekommer inne i method1metoden. Dette fører til at metoden avsluttes umiddelbart. Det ville føre til at hovedmetoden avsluttes hvis ikke for try-catch- blokken."

"Hvis et unntak oppstår inne i en prøveblokk , fanges det opp i catch- blokken. Resten av koden i try-blokken vil ikke bli utført. I stedet vil catch- blokken begynne å bli utført. "

"Jeg skjønner det ikke."

"Med andre ord fungerer koden slik:

1. Hvis et unntak oppstår inne i en prøveblokk , slutter koden å bli utført der unntaket oppstod og catch- blokken begynner å bli utført.

2. Hvis det ikke forekommer noe unntak, kjøres try-blokken til slutten , og catch- blokken blir ikke utført. "

"Hu h?"

"Se for deg at vi etter hvert metodekall sjekker om metoden returnerte normalt eller ble brått avsluttet som et resultat av et unntak. Hvis det er et unntak, så flytter vi til å utføre catch-blokken (hvis det er en) for å fange opp unntaket. Hvis det ikke er noen catch-blokk, avslutter vi den gjeldende metoden, og metoden som ringte oss utfører den samme kontrollen."

— Jeg tror jeg har fått det til nå.

"Utmerket."

"Hva betyr "Unntak" i fangstsetningen?"

" Alle unntak er klasser som arver Exception-klassen. Vi kan fange et bestemt unntak ved å spesifisere unntaksklassen i catch -blokken, eller vi kan fange opp alle unntak ved å spesifisere deres felles overordnede klasse – Exception. Da kan vi få alle nødvendige feil informasjon fra variabelen e (den lagrer en referanse til unntaksobjektet)."

"Kult! Hvis forskjellige unntak forekommer i metoden min, kan jeg da behandle dem annerledes?"

"Ikke bare kan du, men du bør. Du kan gjøre det slik:"

Eksempel:
public class ExceptionExample2
{
    public static void main(String[] args)
    {
        System.out.println("Program starts");

        try
        {
            System.out.println("Before calling method1");
            method1();
            System.out.println("After calling method1. This will never be shown");
        }
        catch (NullPointerException e)
        {
           System.out.println("Null reference. Exception has been caught");
        }
        catch (ArithmeticException e)
        {
            System.out.println("Division by zero. Exception has been caught");
        }
        catch (Exception e)
        {
            System.out.println("Any other errors. Exception has been caught");
        }

        System.out.println("Program is still running");
    }

    public static void method1()
    {
        int a = 100;
        int b = 0;
        System.out.println(a / b);
    }
}

" Prøvingsblokken kan pares med flere fangstblokker , som hver vil fange opp de angitte typene unntak."

"Jeg tror jeg forstår. Jeg kan ikke skrive dette selv ennå, men hvis jeg kommer over det i kode, blir jeg ikke redd."