Exercise index of this lecture   Alphabetic index   Course home   

Exercises and solutions
Undtagelseshåndtering


10.1   Undtagelser i tallæsningsprogrammet  

Én af de første øvelser vi lavede i kurset (lektion 2) gik ud på at indlæse et tal fra tastaturet ved at læse en række enkelte tegn. Genfind jeres løsning på denne opgave, eller tag min løsning , som også findes på filen talLaesning.java

  • Hvorfor erklærer readInt metoden at den kaster undtagelsen IOException?
  • Find tilbage det sted i Java API dokumentationen, der beskriver at der kan forekomme en exception i metoden readInt.
Vi går nu over til at foretage forskellige mindre ændringer i programmet fra lektion 2. Vi håndterer IOException og introducerer en anden mere specifik form for undtagelse:
  • Lav nu en variant af programmet fra lektion 2 som - på én eller anden måde - håndterer IOException. Vores beslutning kan f.eks. være at returnere 0 hvis der forekommer en IO undtagelse når vi læser fra standard input.
  • Der er naturligvis problemer hvis vi læser bogstaver eller specialtegn i metoden readInt. Definer nu selv en exception klasse NumberReadException; Vi ønsker at kaste en instans af denne undtagelse fra readInt hvis vi læser et bogstav eller et specialtegn.

Solution
Lad os først indse, hvorfor den oprindelige version af readInt kaster en IOException. Årsagen er at metoden readLine i klassen BufferedeReader kan kaste en IOException. Dette forplanter sig til vores metode readInt, idet vi ikke håndterer denne undtagelse i readInt.

Hvad angår den anden del af løsningen definerer vi klassen NumberReadException som en specialisering af Exception, og vi kaster den når vi møder et 'fremmed tegn' i et tal. Se min løsning her.


10.2   Klassificering af undtagelser i CircularList  

I klassen CircularList , som vi første gang mødte i lektionen om arrays og lister, er der flere forhold som på en naturlig måde giver anledning til kastning af undtagelser

  • Kortlæg først problemet ved at liste de mulige undtagelser, som kan forekomme i klassen
  • Design om nødvendigt et lille hierarki af undtagelsesklasser, som klassificerer fejlene. Hierarkiets rod bør være CircularListException.
Resten af opgaven går ud på at modificere klassen CircularList således at de respektive metoder i klassen kaster relevante exceptions.

Tag evt. udgangspunkt i min løsning fra den tidligere lektion.

Solution
Efter en konkret analyse viser det sig, at alle problemer i CircularList stammer fra forsøg på at tilgå elementer i en liste, som er tom. I nogle situationer vil vi aflæse elementet, i andre ønsker vi at slette det.

Vi definerer derfor en exception, RetrieveFromEmptyList, som en subklasse af den ønskede klasse CircularListException. Ligeledes definerer vi DeleteInEmptyList, der også er en subklasse af CircularListException. Med denne organisering er vi vel forberedte på situationen, hvor andre problemer vil kunne opstå i listen. Man kunne naturligvis også vælge at slå disse tre klasser sammen til én.

Vi kan bemærke, at nogle præbetingelser på operationer i CircularList er gjort ganske svage: retrieveFirst og retrieveLast returnerer null hvis listen er tom. Vi kunne vælge en prebetingelser der kræver en ikke tom liste; hvis prebetingelsen ikke overholdes kan vi kaste en exception. Dette vælger vi dog ikke at gøre her.

Her er et link til min løsning.

Lad mig henlede opmærksomheden på de steder, hvor de exception-kastende private hjælpe metoder firstLinkable og butLastLinkable bliver kaldt. Kaldene forekommer i tilstande, hvor der ikke vil opstå undtageler. Alligevel skal vi overholde 'catch or specify' princippet. Her vælger vi en pseudo håndtering (catch), som under normale omstændigheder aldrig bør være aktuel. Man kan i høj grad diskutere, om ikke det var bedre at specificere en exception på de berørte metoder.

Jeg må konstatere, at det var ganske besværligt at indføre exception handling i dette program. Nok netop lige så besværlig, at man spørger sig selv, om det er umagen værd...


Generated: Monday March 31, 2008, 12:09:12
on the system cs-unix