User Tools

Site Tools


linuxbog.old:java:java-exception-tvungen
Linux - Friheden til at programmere i Java: Version 0.7.20040516 - 2020-12-31
forrige Kapitel 14. Undtagelser og køretidsfejl næste

14.3. Undtagelser med tvungen håndtering

Indtil nu har oversætteren accepteret vores programmer, hvad enten vi håndterede eventuelle undtagelser eller ej, dvs. det var helt frivilligt, om vi ville tage højde for de mulige fejlsituationer.

Imidlertid er der nogle handlinger, der kræver håndtering, bl.a.:

  • læsning og skrivning af filer (kaster bl.a.: FileNotFoundException, IOException)
  • netværkskommunikation (UnknownHostException, SocketException, IOException)
  • databaseforespørgsler (SQLException)
  • indlæsning af klasser (ClassNotFoundException)

Når programmøren kalder metoder, der kaster disse undtagelser, skal han fange dem.

14.3.1. Fange undtagelser eller sende dem videre

Som eksempel vil vi indlæse en linje fra tastaturet og udskrive den på skærmen:

import java.io.*;
public class TastaturbrugerFejl 
{
  public static void main(String arg[]) 
  {
    BufferedReader ind = new BufferedReader(new InputStreamReader(System.in));
    String linje;
    linje = ind.readLine();
    System.out.println("Du skrev: "+linje);
  }
}

Metoden readLine() læser en linje fra datastrømmen (tastaturet), men når den udføres, kan der opstå en IOException-undtagelse. Oversætteren tvinger os til at tage højde for den mulige undtagelse:

TastaturbrugerFejl.java:8: unreported exception java.io.IOException; must be caught or declared to be thrown
              linje = ind.readLine();

Fejlmeddelelsen ville på dansk lyde: “ I TastaturbrugerFejl.java linje 8 er der en uhåndteret undtagelse IOException; den skal fanges, eller det skal erklæres, at den bliver kastet ”:

Vi er tvunget til enten at fange undtagelsen ved at indkapsle koden i en try-catch-blok, f.eks.:

//try {// linje = ind.readLine();
      System.out.println("Du skrev: "+linje); //} catch (Exception u) {// u.printStackTrace(); //}//

eller erklære, at den bliver kastet , dvs. at den kan opstå i main(). Det gør man med ordet throws :

public static void main(String arg[]) //throws IOException//

Det sidste signalerer, at hvis undtagelsen opstår, skal metoden afbrydes helt, og kalderen må håndtere fejlen (i dette tilfælde er det systemet, der har kaldt main(), men oftest vil det være os selv).

Undtagelser med tvungen håndtering skal enten fanges (med try-catch i metodekroppen) eller sendes videre til kalderen (med throws i metodehovedet)

14.3.2. Konsekvenser af at sende undtagelser videre

Figur 14-1. Java

{linuxbog:java:Nordfalk1515447.png}

Det har konsekvenser at sende undtagelser videre, for da skal kalderen håndtere dem. Her er et eksempel: Lad os sige, at vi har uddelegeret læsningen fra tastaturet til en separat klasse, der kan læse en linje fra tastaturet med læsLinje() og evt. omsætte den til et tal med læsTal():

import java.io.*;

public class Tastatur
{
  BufferedReader ind;

  public Tastatur()
  {
    ind = new BufferedReader(new InputStreamReader(System.in));
  }

  public String læsLinje()
  {
    try {
      String linje = ind.readLine();
      return linje;
    } catch (IOException u)
    {
      u.printStackTrace();
    }
    return null;
  }

  public double læsTal()
  {
    String linje = læsLinje();
    return Double.parseDouble(linje);
  }
}

Herover fanger vi undtagelsen IOException ved dens “rod” i læsLinje().

Den kunne gøres simplere ved at fjerne håndteringen og erklære IOException kastet:

public String læsLinje() throws IOException
  {
    String linje = ind.readLine();
    return linje;
  }

Nu sender læsLinje() undtagelserne videre, så nu er det kalderens problem at håndtere den.

Vi kalder selv metoden fra læsTal(), så her er vi nu enten nødt til at fange eventuelle undtagelser:

public double læsTal()
  {
    try {
      String linje = læsLinje();
      return Double.parseDouble(linje);
    } catch (IOException u)
    {
      u.printStackTrace();
    }
    return 0;
  }

… eller igen sende dem videre. Herunder er Tastatur igen, men IOException kastes nu videre fra begge metoder.

import java.io.*;

public class TastaturKasterUndtagelser
{
  BufferedReader ind;

  public TastaturKasterUndtagelser()
  {
    ind = new BufferedReader(new InputStreamReader(System.in));
  }

  public String læsLinje() //throws IOException// {
    String linje = ind.readLine();
    return linje;
  }

  public double læsTal() //throws IOException// {
    String linje = læsLinje();
    return Double.parseDouble(linje);
  }
}

Om man skal fange undtagelser eller lade dem “ryge videre” afhænger af, om man selv kan håndtere dem fornuftigt, eller kalderen har brug for at få at vide, at noget gik galt.

Hvad sker der f.eks. i Tastatur, hvis der opstår en undtagelse i læsLinje() kaldt fra læsTal()?

Jo, læsLinje() returnerer en null-reference til læsTal(), der sender denne reference til parseDouble(), der sandsynligvis “protesterer” med en NullPointerException, for man kan ikke konvertere null til et tal. Der opstår altså en følgefejl, fordi vi fortsætter, som om intet var hændt.

I dette tilfælde må TastaturKasterUndtagelser altså siges at være bedst, selvom den altså giver kalderen mere arbejde.


forrige hjem næste
At fange og håndtere undtagelser op Præcis håndtering af undtagelser
linuxbog.old/java/java-exception-tvungen.txt · Last modified: by 127.0.0.1

Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 4.0 International
CC Attribution-Share Alike 4.0 International Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki

Brug af AI : Al tekst kán være uddrag af AI genereret tekst og kan være fejlbehæftet.
AI kan lave fejl og det kan mennesker også, men al tekst er gennemgået af et menneske for fejl, og personlig bias kan være tilføjet.