Kapitel 14. Undtagelser og køretidsfejl

Indhold:

Kapitlet forudsættes i resten af bogen, og evnen til at kunne læse et stakspor er vigtigt, når man skal finde fejl i sit program.

Forudsætter Kapitel 5, Definition af klasser (Kapitel 6, Nedarvning er en fordel).

Som programmør skal man tage højde for fejlsituationer, som kan opstå, når programmet udføres. Det gælder f.eks. inddata fra brugeren, der kan være anderledes, end man forventede (brugeren indtaster f.eks. bogstaver et sted, hvor programmet forventer tal), og adgang til ydre enheder, som kan være utilgængelige, f.eks. filer, printere og netværket.

Hvis programmet prøver at udføre en ulovlig handling, vil der opstå en undtagelse (eng.: Exception), og programudførelsen vil blive afbrudt på det sted, hvor undtagelsen opstod.

Lad os undersøge nærmere, hvad der sker. Herunder prøver vi at indeksere ud over en vektors grænser:


import java.util.*;

public class SimpelUndtagelse
{
  public static void main(String[] args)
  {
    System.out.println("Punkt A");       // punkt A
    Vector v = new Vector();
    System.out.println("Punkt B");       // punkt B
    v.elementAt(5);
    System.out.println("Punkt C");       // punkt C
  }
}

og


Punkt A
Punkt B
java.lang.ArrayIndexOutOfBoundsException: 5 >= 0
  at java.util.Vector.elementAt(Vector.java:417)
  at SimpelUndtagelse.main(SimpelUndtagelse.java:10)
Exception in thread "main"

Når vi kører programmet, kan vi se, at det stopper mellem punkt B og C med en fejl:


java.lang.ArrayIndexOutOfBoundsException: 5 >= 0

Den efterfølgende kode udføres ikke, og vi når aldrig punkt C.

Programudførelsen afbrydes, når der opstår en undtagelse

I dette kapitel vil vi illustrere, hvordan undtagelser opstår, og hvordan de håndteres. Af plads- og overskuelighedshensyn er eksemplerne ret små, og undtagelseshåndtering derfor ikke specielt nødvendig. Man skal forestille sig større situationer, hvor der opstår fejl, der ikke lige er til at gennemskue (i dette eksempel kunne der være meget mere kode ved punkt B).

Man kan tænke på undtagelser som en slags protester. Indtil nu har vi regnet med, at objekterne pænt "parerede ordre", når vi gav dem kommandoer eller spørgsmål (kaldte metoder). Fra nu af kan metoderne "spænde ben" og afbryde programudførelsen, hvis situationen er uacceptabel.

Det er det, som elementAt(5) på den tomme Vector gør: Som svar på "giv mig element nummer 5" kaster den ArrayIndexOutOfBoundsException og siger "5 >= 0", dvs. "det kan jeg ikke, for 5 er større end antallet af elementer i vektoren, som er 0!".

14.1. Almindelige undtagelser

Ud over ArrayIndexOutOfBoundsException som beskrevet ovenfor kan der opstå en række andre fejlsituationer. De mest almindelige er kort beskrevet nedenfor.

Der opstår en undtagelse af typen NullPointerException, hvis man kalder metoder på en variabel, der ingen steder refererer hen (en objektreference, der er null):


    Vector v = null;
    v.addElement("x");

Resultatet bliver:


Exception in thread "main" java.lang.NullPointerException
        at SimpelUndtagelse.main(SimpelUndtagelse.java:6)

Hvis man laver aritmetiske udregninger, kan der opstå undtagelsen ArithmeticException, f.eks. ved division med nul:


    int a = 5;
    int b = 0;
    System.out.print(a/b);

Resultatet bliver:


Exception in thread "main" java.lang.ArithmeticException: / by zero
        at SimpelUndtagelse.main(SimpelUndtagelse.java:7)

ClassCastException opstår, hvis man prøver at typekonvertere en objektreference til en type som objektet ikke er, f.eks. en Gade til et Rederi:


    Felt f = new Gade("Gade 2", 10000, 400, 1000);
    Rederi r = (Rederi) f;

Resultatet bliver:


Exception in thread "main" java.lang.ClassCastException: Gade
        at SimpelUndtagelse.main(SimpelUndtagelse.java:6)