Ausnahmen

Werbung
Ausnahmen
DVG1 - 11 - Ausnahmen
1
Was sind Programmfehler?
DVG1 - 11 - Ausnahmen
Programm erzielt gar kein Ergebnis.
Berechnetes Ergebnis stimmt nicht mit dem erwarteten überein.
Programm verhält sich falsch oder unzweckmäßig während der
Abarbeitung, z.B.:
Absturz bei falscher Eingabe
unendliche Zyklen bei fehlerhaften Parametern
kein Ende bei bestimmten Aufgaben
Programm arbeitet nicht reproduzierbar falsch
2
Fehlerursachen
DVG1 - 11 - Ausnahmen
fehlerhafte Konzeption
fehlerhafter Algorithmus
fehlerhafte Syntax
fehlerhafte Realisierung der Konzeption bzw. des Algorithmus
fehlerhafte Bedienung bzw. fehlerhafte Parameter
Fehler innerhalb der VM
fehlerhaftes Betriebssystem
fehlerhafte Hardware
3
Ausnahmen in JAVA
Befassen sich mit Fehlern, die zur Ausführungszeit eines Programms
auftreten. Z.B.:
Ein-/Ausgabe-Fehler, z.B.:
Lesefehler bei
System.in.read(buffer);
DVG1 - 11 - Ausnahmen
Laufzeitfehler, z.B.:
int i = Integer.parseInt(args[0]);
führt bei args[0]=="abc" zu einer Ausnahme
"NumberFormatException"
arithmetische Fehler, z.B.:
int i = 1/0;
führt zu einer Ausnahme "ArithmeticException"
JAVA bietet komfortable und dennoch einfache Möglichkeiten zur
Behandlung von Ausnahmen.
4
public class test1
{
public static void main ( String [] args)
{
int i = Integer.parseInt(args[0]);
System.out.println("Es wurde der Wert "+i+" eingegeben.");
}
}
DVG1 - 11 - Ausnahmen
"java test1 11234" ergibt:
Es wurde der Wert 11234 eingegeben.
"java test1 11234xx" ergibt:
Exception in thread "main" java.lang.NumberFormatException: 11234xx
at java.lang.Integer.parseInt(Compiled Code)
at java.lang.Integer.parseInt(Integer.java:458)
at test1.main(test1.java:5)
5
Fehlerursache: 11234xx lässt sich nicht in eine int-Größe
umwandeln!
Compilermeldung exakt und hilfreich für den Programmentwickler.
Der Anwender wird durch die Meldung verunsichert und erfährt nicht,
was er falsch gemacht hat.
Typischer Anruf des Anwenders: „Ich habe alles genau so gemacht
wie immer, aber seit heute funktioniert nichts mehr. Was ist los?“
DVG1 - 11 - Ausnahmen
6
DVG1 - 11 - Ausnahmen
public class test2
{
public static void main ( String [] args) {
try
{
int i = Integer.parseInt(args[0]);
System.out.println("Es wurde der Wert "+i+" eingegeben.");
}
catch (NumberFormatException e)
{
System.out.println(args[0]+
" kann nicht in eine int-Groesse verwandelt werden!\n"+
"Der Parameter darf nur aus Ziffern 0..9 bestehen!");
}
}
}
"java test2 11234" ergibt:
Es wurde der Wert 11234 eingegeben.
"java test2 11234xx" ergibt:
11234xx kann nicht in eine int-Groesse verwandelt werden!
Der Parameter darf nur aus Ziffern 0..9 bestehen!
"java test2" ergibt:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
7
at test2.main(test2.java:7)
DVG1 - 11 - Ausnahmen
public class test3
{
public static void main ( String [] args)
{
try
{
int i = Integer.parseInt(args[0]);
System.out.println("Es wurde der Wert "+i+" eingegeben.");
}
catch (NumberFormatException e)
{
System.out.println(args[0]+
" kann nicht in eine int-Groesse verwandelt werden!\n"+
"Der Parameter darf nur aus Ziffern 0..9 bestehen!");
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println(
"Es muss mindestens ein Parameter angegeben werden!");
}
}
}
"java test3" ergibt:
8
Es muss mindestens ein Parameter angegeben werden!
DVG1 - 11 - Ausnahmen
public class test4
{
public static void main ( String [] args){
try
{
int i = Integer.parseInt(args[0]);
System.out.println("Es wurde der Wert "+i+" eingegeben.");
}
catch (NumberFormatException e)
{
System.out.println(args[0]+
" kann nicht in eine int-Groesse verwandelt werden!\n"+
"Der Parameter darf nur aus Ziffern 0..9 bestehen!");
}
catch (ArrayIndexOutOfBoundsException e)
{
System.out.println(
"Es muss mindestens ein Parameter angegeben werden!");
}
finally
{
System.out.println(
"Das Programm ist mehr oder weniger erfolgreich beendet.");
}
} }
Egal wie das Programm beendet wird es gibt die Meldung aus:
9
Das Programm ist mehr oder weniger erfolgreich beendet.
Allgemeine Form
DVG1 - 11 - Ausnahmen
try
{
// Block in dem Ausnahmen auftreten können
}
catch (Ausnahmetyp1 name)
{
// Block in dem der Ausnahmetyp1 behandelt wird
}
...
catch (AusnahmetypN name)
{
// Block in dem der AusnahmetypN behandelt wird
}
finally
{
// finally- Block
}
10
DVG1 - 11 - Ausnahmen
Nach einem try-Block muß immer mindestens ein catch-Block
existieren.
Beim Eintreten einer Ausnahme wird der erste passende catch-Block
abgearbeitet.
Der finally-Block muß immer nach allen catch-Blöcken stehen.
Der finally-Block wird abgearbeitet:
nach dem „normalen“ Ende des try-Blockes
nach einer behandelten Ausnahme
vor einer Ausnahme, die weitergereicht wird
nach Verlassen des try-Blockes über eine break-, continue- oder
return-Anweisung
11
try-Block Ausnahme
DVG1 - 11 - Ausnahmen
Ausnahmetyp1
Catch-Block 1
Ausnahmetyp2
Catch-Block 2
AusnahmetypN
Catch-Block N
finally-Block
12
DVG1 - 11 - Ausnahmen
import java.io.*;
public class test5
{
public static void main (String [] args)
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String s = br.readLine();
System.out.println("Es wurde eingegeben :\n\""+s+"\"");
}
}
javac test5.java ergibt
test5.java:9: unreported exception java.io.IOException; must
be caught or declared to be thrown
System.in.read(buffer);
13
DVG1 - 11 - Ausnahmen
public class test6
{
public static void main (String [] args){
System.out.println("Gebe bitte eine Zeichenkette ein : ");
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
try
{
String s = br.readLine();
System.out.println("Es wurde eingegeben :\n\""+s+"\"");
}
catch (java.io.IOException e)
{
}
}
}
java test6 ergibt
Gebe bitte eine Zeichenkette ein :
Das ist ein Test.
Es wurde eingegeben :
"Das ist ein Test."
14
geprüfte bzw. ungeprüfte Ausnahmen
Ausnahmen NumberFormatException und
ArrayIndexOutOfBoundsException brauchten nicht abgefangen
zu werden, d.h. es musste keine catch-Anweisung für diese
Ausnahmen angegeben werden. ==> ungeprüfte Ausnahmen
Ausnahme java.io.IOException musste abgefangen werden.
==> geprüfte Ausnahmen
DVG1 - 11 - Ausnahmen
15
Ausnahmenhierarchie
Throwable
Error
Exception
ungeprüft
geprüft ungeprüft
Eigene Ausnahmen
Eigene Ausnahmen
nicht empfohlen
DVG1 - 11 - Ausnahmen
meist benutzt
IOException
geprüft
Eigene Ausnahmen
möglich
RuntimeException
ungeprüft
Eigene Ausnahmen
nicht empfohlen
16
Weiterreichen von Ausnahmen
Eine Ausnahme muss nicht in der Methode behandelt werden, in der sie
auftritt. Sie kann auch an die aufrufende Methode weitergereicht
werden.
Das wird dem Compiler durch die throws-Klausel einer MethodenDeklaration mitgeteilt, z.B.:
public static String readString() throws
java.io.IOException
DVG1 - 11 - Ausnahmen
17
DVG1 - 11 - Ausnahmen
import java.io.*;
public class test7
{
public static void main (String [] args)
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
System.out.println(
"Es wurde eingegeben :\n\""+readString()+"\"");
}
public static String readString()
{
try
{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
return br.readLine();
}
catch (IOException e)
{
return null;
}
}
}
18
import java.io.*;
DVG1 - 11 - Ausnahmen
public class test8
{
public static void main (String [] args) throws IOException
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
System.out.println(
"Es wurde eingegeben :\n\""+readString()+"\"");
}
public static String readString() throws IOException
{
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
return br.readLine();
}
}
19
Auslösen von Ausnahmen
Ausnahmen können durch das Programm ausgelöst werden, durch
throw new Ausnahme (...);
DVG1 - 11 - Ausnahmen
20
public class test9
{
public static void main (String [] args)
{
int z = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
DVG1 - 11 - Ausnahmen
if ( n == 0)
{
System.out.println("Der Nenner ist == 0 !");
throw new ArithmeticException("Nenner ist 0");
}
else
{
System.out.println(z+"/"+n+"="+z/n);
}
}
}
java test9 1 0 ergibt
Der Nenner ist == 0 !
Exception in thread "main" java.lang.ArithmeticException: Nenner ist 0
21
at test9.main(test9.java:11)
Eigene Ausnahmen
Ausnahmen sind Klassen, die von anderen Ausnahmeklassen
abgeleitet sind.
Einfachste Form:
class Ausnahme extends OberKlasse { }
z.B.:
class Ausnahme extends Exception { }
DVG1 - 11 - Ausnahmen
22
public class test10
{
public static int f ( int z, int n ) throws Ausnahme
{
if ( n == 0 )
{
throw new Ausnahme();
}
return z/n;
}
DVG1 - 11 - Ausnahmen
public static void main (String [] args)
{
int z = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
try
{
System.out.println(z+"/"+n+"="+f(z,n));
}
catch (Ausnahme e)
{
System.out.println(e);
}
}
}
class Ausnahme extends Exception { }
java test10 10 0 ergibt
Ausnahme
23
Lesemethoden
Was wollen wir einlesen?
Zeichenketten, Texte
numerische Daten
ganze Zahlen (byte, short, int, long)
Gleitkommazahlen (float, double)
Felder
Auswahlen, Menüs
DVG1 - 11 - Ausnahmen
24
Einlesen von Zeichenketten
DVG1 - 11 - Ausnahmen
System.in realisiert Eingabestrom von bytes, wir benötigen gepufferte
Eingabe von Unicodezeichenketten.
InputStreamReader rd = new
InputStreamReader(System.in) erzeugt Eingabestrom von
Unicodezeichen.
BufferedReader br = new BufferedReader(rd) erzeugt
gepufferten Eingabestrom von Unicodezeichen.
Zusammen:
BuffredReader br = new BufferedReader(new
InputStreamReader(System.in))
25
public static double readDouble (
)
{
for (;;)
{
try
{
String s = readString();
DVG1 - 11 - Ausnahmen
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print("Nochmal:");
}
}}
26
public static double readDouble (
)
{
for (;;)
{
try
{
String s = readString();
DVG1 - 11 - Ausnahmen
if ( s.compareToIgnoreCase("nan")==0 ) return 0.0/0.0;
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print("Nochmal:");
}
}}
27
public static double readDouble (
double def )
{
for (;;)
{
try
{
String s = readString();
DVG1 - 11 - Ausnahmen
if ( s.compareToIgnoreCase("nan")==0 ) return 0.0/0.0;
if ( s.length() == 0 ) return def;
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print("Nochmal:");
}
}}
28
public static double readDouble (
String prompt, double def, String colon)
{
System.out.print(prompt+" ["+def+"] "+colon);
for (;;)
{
try
{
String s = readString().trim();
DVG1 - 11 - Ausnahmen
if ( s.compareToIgnoreCase("nan")==0 ) return 0.0/0.0;
if ( s.length() == 0 ) return def;
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print("Nochmal ["+def+"] "+colon);
}
}}
29
public static double readDouble (
String prompt, String errorMessage, double def, String colon)
{
System.out.print(prompt+" ["+def+"] "+colon);
for (;;)
{
try
{
String s = readString().trim();
DVG1 - 11 - Ausnahmen
if ( s.compareToIgnoreCase("nan")==0 ) return 0.0/0.0;
if ( s.length() == 0 ) return def;
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print(errorMessage+" ["+def+"] "+colon);
}
}}
30
DVG1 - 11 - Ausnahmen
public static double readDouble (
String prompt, String errorMessage, double def, String colon)
{
String helpText =
"Geben Sie bitte eine double-Groesse ein.\n"+
"Die Eingabe darf aus den Ziffern 0..9 bestehen. Ausserdem koennen\n"+
"ein Dezimalpunkt, das Zeichen \"E\" fuer den Exponenten,\n"+
"sowie Vorzeichen vor der Zahl und dem Exponenten angegeben werden.\n"+
"NaN erhaelt man durch Eingaben von \"NaN\".\nz.B.: -1.234567E-123";
System.out.print(prompt+"(?=help) ["+def+"] "+colon);
for (;;)
{
try
{
String s = readString().trim();
if ( s.compareTo("?")==0 )
{
System.out.println(helpText);
System.out.print(prompt+"(?=help) ["+def+"] "+colon);
continue;
}
if ( s.compareToIgnoreCase("nan")==0 ) return 0.0/0.0;
if ( s.length() == 0 ) return def;
return Double.parseDouble(s);
}
catch ( NumberFormatException e )
{
System.out.print(errorMessage+"(?=help) ["+def+"] "+colon);
}
31
}}
Herunterladen