§6 Fehlerbehandlung mit Java Fehlerbehandlung

Werbung
GhK
FB 17 Mathematik / Informatik
§6
Fehlerbehandlung mit Java
Ausnahmen, Handling, Auswerfen
GhK
Fehlerbehandlung
FB 17 Mathematik / Informatik
• In jedem Programm kann es zur Laufzeit zu Fehlern
kommen, die verschiedenste Ursache haben können, z.B.:
– Falsches Eingabenformat
– illegaler Speicherzugriff (zu hoher Array-Iindex etc.)
– fehlende Resourcen (keine Datei, lesen am Dateiende etc.)
• In Java werden solche Fehler als
– Exception : Ausnahme, behebbarer Fehler
– Error
oder
: fataler Fehler
ausgeworfen und können dann im Programm ggf.
abgefangen und entsprechend behandelt werden.
• Java hat damit eine deutliche (optische) Trennung
zwischen Programmablauf und Fehlerbehandlung.
GhK
Ausnahmen
FB 17 Mathematik / Informatik
//Ausnahmen.java
import java.io.*;
class Ausnahmen
{ public static void main(String[] args)
{PrintWriter out = new PrintWriter(System.out, true);
int i = Integer.parseInt(args[0]);
out.println("i = " + i);
}
}
• Die Deklaration von i kann aus zwei Gründen schiefgehen:
– Ausnahmen ist ohne Parameter aufgerufen worden, d.h. args hat 0 Felder und es
wird eine ArrayIndexOutOfBoundsException ausgeworfen.
– Der erste Parameter von Ausnahmen ist nicht als Integer interpretierbar
(z.B. "x1234") und es wird eine NumberFormatException ausgeworfen.
GhK
Ausnahmetypen
FB 17 Mathematik / Informatik
ClassNotFoundException
CloneNotSupportedException
IllegalAccessException
InstantiationException
Exception
InterruptedException
NoSuchFieldException
NoSuchMethodException
Throwable
RuntimeException
LinkageError
Error
VirtualMachineError
ThreadDeath
GhK
ungeprüfte Fehler
FB 17 Mathematik / Informatik
• Java verlangt in der Regel, daß Fehlersituationen überprüft
(abgefangen) werden müssen. Ausnahmen sind alle Errors
und die RuntimeExceptions.
• Ein LinkageError wie etwa AbstractMethodError,
NOSuchFieldError oder NoSuchMethodError oder ein
VirtualMachineError wie etwa OutOfMemoryError,
StackOverflowError, InternalError oder UnknownError kann
zur Laufzeit nicht sinnvoll aufgefangen werden und braucht
es deshalb auch nicht.
RuntimeException wie etwa ArithmeticException,
NullPointerException, NumberFormatException,
ArrayIndexOutOfBoundsException ist manchmal nur mit
• Eine
einem
Aufwand aufzufangen, der den Nutzen nicht aufwiegt,
darum braucht er nicht unbedingt behandelt zu werden.
GhK
Standard-Ausnahmebehandlung
FB 17 Mathematik / Informatik
• Java hat einen Standard-Ausnahmehandler, der den Typ
der Ausnahme und die Reihenfolge der Methodenaufrufe,
die zu dieser Ausnahme geführt haben (StackTrace) aus.
d.h. nicht abgefangene Ausnahmen werden mit
Programmabbruch bestraft!
• Dies kann man auch explizit tun
– out.print(e)
gibt den Ausnahmetyp aus
– e.printStackTrace()
gibt die Methodenaufrufe aus
• Ausnahmen können auch mit einem erklärenden Text
versehen sein, der dann ausgegeben werden kann mit
– out.println(e.getMessage())
GhK
try-catch
FB 17 Mathematik / Informatik
• Um in Java eine Ausnahme abzufangen, die durch einen
Befehl ***** ausgeworfen werden könnte, verwendet man
das Schlüsselwort try {*****} .
• Nach einer try-Klausel muß dann mindestens eine catchKlausel (Handler) folgen:
– try { int i = Integer.parseInt(args[0]);
out.println("i= "+i);
}
catch (NumberFormatException e)
{ out.print("Als erstes Kommandozeilen-Argument");
out.println("wird ein int-Wert benötigt !");
}
catch (ArrayOutOfBoundsException e)
{ out.print("Aufruf in der Form :");
out.println("java <Programmname> <int-Wert>"):
}
GhK
Beispiel
FB 17 Mathematik / Informatik
// Argumente.java
import java.io.*;
class Argumente
{ static PrintWriter out = new PrintWriter(System.out,true);
static int n=0;
public static void main(String[] args)
{ for (n=0;;n++)
{ try {out.println((n+1) + " : " + args[n]);}
catch(ArrayIndexOutOfBoundsException e){break;}
}
out.println("****Ende der Argumentenliste****");
}
}
GhK
geschachtelte try-Blöcke
FB 17 Mathematik / Informatik
• Das obige Beispiel könnte auch geschachtelt werden:
– try
{try { int i = Integer.parseInt(args[0]);
out.println("i= "+i);
}
catch (NumberFormatException e)
{ out.print("Als erstes Kommandozeilen-Argument");
out.println("wird ein int-Wert benötigt !");
}
}
catch (ArrayOutOfBoundsException e)
{ out.print("Aufruf in der Form :");
out.println("java <Programmname> <int-Wert>");
}
GhK
finally-Block
FB 17 Mathematik / Informatik
• statt einer catch-Klausel oder nach allen catch-Klauseln
darf noch ein Block finally {...} stehen, in der z.B. das
Schließen von Dateien, Datenbanken, Netzverbindungen
o.Ä. erledigt werden kann.
• Der finally-Block wird in jedem Fall ausgeführt,
gleichgültig ob:
– keine Ausnahme ausgeworfen wird
– der try-Block durch ein explizites return verlassen wird
– eine Ausnahme ausgeworfen wird, die durch ein catch abgefangen wird
– eine Ausnahme ausgeworfen wird, die nicht abgefangen wird
GhK
Regeln für try
FB 17 Mathematik / Informatik
• try-Blöcke können ineinander geschachtelt sein.
• Wird in einem try-Block keine Ausnahme ausgeworfen, so
werden alle unmittelbar danach stehenden catch-Blöcke
(Handler) übersprungen.
• Wird eine Ausnahme ausgeworfen,
- so wird unter den nachfolgenden Handlern der erste
ausgeführt, der auf die Ausnahme passt und alle
darauffolgenden Handler werden übersprungen.
- Wird kein passender Handler gefunden so wird hinter
dem umfassenden try-Block nach ihm gesucht u.s.w.
- Gibt es keinen umfassenden try-Block mehr, so wird der
Standard-Ausnahmehandler eingesetzt (Dump + Abbruch).
GhK
throws-Klausel
FB 17 Mathematik / Informatik
• In einer Methodendeklaration kann nach dem Namen ein
throws mit einer Liste von Typen stehen, die alle Subtypen
von Throwable sein müssen.
• Dies zeigt an, daß die Methode mit einer der in der Liste
aufgeführten Ausnahmen abbrechen kann.
• Die throws-Klausel muß stehen, wenn die ausgeworfenen
Ausnahmen nicht vom Typ Error oder RuntimeException
sind und nicht innerhalb der Methode abgefangen werden
können oder sollen.
• Mit diesem Mechanismus kann Java kontrollieren, ob alle
Ausnahmen (außer Errors und RuntimeExceptions) auch
abgefangen werden.
GhK
Hierarchie(1)
FB 17 Mathematik / Informatik
// Hierarchie.java
import java.io.*;
class Hierarchie
{ static PrintWriter out=new PrintWriter(System.out,true);
static boolean superKlasse(Class cs, String t)
// Fehler
{ Class ct = Class.forName(t);
if (!cs.isAssignableFrom(ct)) return false;
out.println(t + " ist Subklasse von " + cs);
return true;
}
public static void main(String[] args)
// Fehler
{ if (args.length == 0)
{out.println("Start in der Form java Hierarchie <Name>"
+ "\n!!! voll qualifizierte Klassennamen !!!"
+ "\n(Z.B. java.io.FileNotFoundException)");return;
}
String s = args[0];
if (superKlasse(java.lang.Throwable.class, s))
if (superKlasse(java.lang.Exception.class, s))
{if (superKlasse(java.lang.RuntimeException.class, s));}
else if (superKlasse(java.lang.Error.class, s));
}
}
GhK
Hierarchie(2)
FB 17 Mathematik / Informatik
• Die Methode superKlasse kann in der Zeile
Class ct = Class.forName(t)
eine ClassNotFoundException auswerfen, wenn t kein
gültiger Klassenname ist, darum wird superKlasse ohne
den Zusatz throws ClassNotFoundException nicht
übersetzt.
• Die Methode main verwendet superKlasse, ohne die
ClassNotFoundException abzufangen, daher muß auch sie
mit dem Zusatz throws ClassNotFoundException versehen
werden, damit sie übersetzt werden kann.
• Regel: Exceptions müssen in einer Methode abgefangen oder mit
einer throws-Klausel nach außen weitergereicht werden.
GhK
eigene Ausnahmen
FB 17 Mathematik / Informatik
• Jeder Programmierer kann natürlich auch eigene
Ausnahmen aus Throwable oder deren Unterklassen
ableiten.
• Ausnahmen könne in einer Methode explizit mit dem Befehl
throw ....
ausgeworfen werden.
• Regel:
Werden Methoden aus Superklassen überschrieben, so
darf die neue Methode nur solche Ausnahmen auswerfen,
die die überschriebene Methode nach ihrer throws-Klausel
auch hätte auswerfen können. Alle sonstigen Ausnahmen
müssen innerhalb der Methode abgefangen werden.
GhK
Beispiel Throw
FB 17 Mathematik / Informatik
// Throw.java
import java.io.*;
import java.util.*;
class Throw
{ static PrintWriter out = new PrintWriter(System.out, true);
static class Closed extends Exception
{ ClosedShop(String text) { super(text);}
}
void connect() throws Closed
{ int tag = Calendar.getInstance().get(Calendar.DAY_OF_WEEK);
if (tag == Calendar.SUNDAY) throw new Closed("sonntag");
if (tag == Calendar.THURSDAY)throw new Closed("donnerstag");
out.println("Heute normaler Betrieb.");
}
public static void main(String[] args)
{ try { new Throw().connect();}
catch (Closed ex)
{ out.println( ex.getMessage() + "s geschlossen.");}
}
}
GhK
Passwortabfrage(1)
FB 17 Mathematik / Informatik
// Login.java
import java.awt.*;import java.awt.event.*;import java.io.*;
class Login extends Frame
{ TextField text;
final int MAX = 5;
int anz = 0;
Login()
// Konstuktor
{ super(" ");
setLayout(new GridLayout(2, 1));
setFont(new Font("Monospaced", Font.PLAIN, 14));
add(new Label("Zum Starten Passwort eingeben"));
add(text = new TextField(20));
text.setEchoChar('*');
text.setBackground(Color.darkGray);
text.setForeground(Color.white);
pack();
text.addActionListener(new ActionListener()
{ public void actionPerformed(ActionEvent e) {Frage();}});
setVisible(true);}
class PasswdEx extends Exception { }
GhK
Passwortabfrage(2)
FB 17 Mathematik / Informatik
public static void main(String[] args)
{new Login();}
void Frage()
{ ++anz;
try
{try
{if (!(text.getText().equals("Passwort")))
throw new PasswdEx();
//exit aus if..
dispose();
//Fenster zerstören
new PrintWriter(System.out, true).println("Login ok");
System.exit(0);}
catch (PasswdEx ex)
{if (anz == MAX) throw ex;
//exit aus try..
text.setEditable(false);
text.setText("");
try {Thread.sleep(1000*anz);}
catch (InterruptedException ign) { }
text.setEditable(true);}}
catch (PasswdEx ex)
{new PrintWriter(System.out, true).println("Login fail");
System.exit(0);}
//exit aus main
}}
GhK
Passwortabfrage(3)
FB 17 Mathematik / Informatik
// LoginA.java
import java.applet.*;
import java.net.*;
...
class LoginA
extends Applet
{ TextField text,nachr;
...
LoginA()// Konstuktor
{ //super(" ");
...
//pack();}
void Frage()
{....
nachr.setEditable(false);
nachr.setText("Login ok");
try {getAppletContext().showDocument
// ruft eine URL auf
(new URL("http://www.neuro.informatik.uni-kassel.de/"));}
catch(java.net.MalformedURLException e){}
GhK
Zeichenfeld
FB 17 Mathematik / Informatik
// Scribble.java
import java.applet.*;import java.awt.*;
public class Scribble extends Applet
{
private int last_x = 0, last_y = 0 ;
//zum Speichern von Punkten
// Aufruf erfolgt beim Anklicken durch den Benutzer.
public void mouseDown(Event e, int x, int y)
{
last_x = x; last_y = y;}
//Position des Klicks merken
// Aufruf erfolgt, wenn Maus mit gedrückter Taste bewegt wird
public void mouseDrag(Event e, int x, int y)
{
Graphics g = getGraphics();
// in g wird gezeichnet
g.drawLine(last_x, last_y, x, y); // Linie vom letzten Punkt
zum aktuellen Punkt
last_x = x ; last_y = y ;}
}
// Position aktualisieren
GhK
FB 17 Mathematik / Informatik
• Dieses
Applet
erlaubt
kleine
Bilder
mit der
Maus
zu
zeichnen.
Zeichenfeld(2)
Herunterladen