04-ausnahmen

Werbung
Ausnahmen
DVG2 - 04
1
Was sind Programmfehler?
 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
DVG2 - 04
2
Fehlerursachen
 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
DVG2 - 04
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);
– 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 aber einfache Möglichkeiten zur Behandlung
von Ausnahmen.
DVG2 - 04
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.");
}
}
"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)
DVG2 - 04
5
 Fehlerursache: 11234xx läßt 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?“
DVG2 - 04
6
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
at test2.main(test2.java:7)
DVG2 - 04
7
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:
Es muss mindestens ein Parameter angegeben werden!
DVG2 - 04
8
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:
Das Programm ist mehr oder weniger erfolgreich beendet.
DVG2 - 04
9
Allgemeine Form
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
}
DVG2 - 04
10
 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
DVG2 - 04
11
try-Block Ausnahme
Ausnahmetyp1
Catch-Block 1
Ausnahmetyp2
Catch-Block 2
AusnahmetypN
Catch-Block N
finally-Block
DVG2 - 04
12
public class test5
{
public static void main (String [] args)
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
byte [] buffer = new byte [80];
int ir=0;
ir = System.in.read(buffer);
if ((char)buffer[ir-1]=='\n') ir--;
if ((char)buffer[ir-1]=='\r') ir--;
String s = new String(buffer,0,ir);
System.out.println("Es wurde eingegeben :\n\""+s+"\"");
}
}
javac test5.java ergibt
test5.java:8: Exception java.io.IOException must be caught, or
it must be declared in the throws clause of this method.
System.in.read(buffer);
DVG2 - 04
13
public class test6
{
public static void main (String [] args)
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
byte [] buffer = new byte [80];
int ir=0;
try
{
ir = System.in.read(buffer);
if ((char)buffer[ir-1]=='\n') ir--;
if ((char)buffer[ir-1]=='\r') ir--;
}
catch (java.io.IOException e)
{
}
String s = new String(buffer,0,ir);
System.out.println("Es wurde eingegeben :\n\""+s+"\"");
}
}
java test6 ergibt
Gebe bitte eine Zeichenkette ein :
Das ist ein Test.
Es wurde eingegeben :
"Das ist ein Test."
DVG2 - 04
14
geprüft bzw. ungeprüfte Ausnahmen
 Ausnahmen NumberFormatException und
ArrayIndexOutOfBoundsException brauchten nicht abgefangen
zu werden, d.h. es mußte keine catch-Anweisung für diese
Ausnahmen angegeben werden. ==> ungeprüfte Ausnahmen
 Ausnahme java.io.IOException mußte abgefangen werden.
==> geprüfte Ausnahmen
DVG2 - 04
15
Ausnahmenhierarchie
Throwable
Error
Exception
ungeprüft
geprüft ungeprüft
Eigene Ausnahmen
Eigene Ausnahmen
nicht empfohlen
meist benutzt
RuntimeException
IOException
ungeprüft
geprüft
Eigene Ausnahmen
Eigene Ausnahmen
nicht empfohlen
möglich
DVG2 - 04
16
Weiterreichen von Ausnahmen
 Eine Ausnahme muß 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
DVG2 - 04
17
public class test7
{
public static String readString()
{
byte [] buffer = new byte [80];
try
{
int ir = System.in.read(buffer);
if ((char)buffer[ir-1]=='\n') ir--;
if ((char)buffer[ir-1]=='\r') ir--;
return new String(buffer,0,ir);
}
catch (java.io.IOException e)
{
return null;
}
}
public static void main (String [] args)
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
System.out.println(
"Es wurde eingegeben :\n\""+readString()+"\"");
}
}
DVG2 - 04
18
public class test8
{
public static String readString() throws java.io.IOException
{
byte [] buffer = new byte [80];
int ir = System.in.read(buffer);
if ((char)buffer[ir-1]=='\n') ir--;
if ((char)buffer[ir-1]=='\r') ir--;
return new String(buffer,0,ir);
}
public static void main (String [] args) throws java.io.IOException
{
System.out.println("Gebe bitte eine Zeichenkette ein : ");
System.out.println(
"Es wurde eingegeben :\n\""+readString()+"\"");
}
}
DVG2 - 04
19
Auslösen von Ausnahmen
 Ausnahmen können durch das Programm ausgelöst werden, durch
throw new Ausnahme (...);
DVG2 - 04
20
public class test9
{
public static void main (String [] args)
{
int z = Integer.parseInt(args[0]);
int n = Integer.parseInt(args[1]);
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
at test9.main(test9.java:11)
DVG2 - 04
21
Eigene Ausnahmen
 Ausnahmen sind Klassen, die von anderen Ausnahmeklassen
abgeleitet sind.
 Einfachste Form:
class Ausnahme extends OberKlasse { }
z.B.:
class Ausnahme extends Exception { }
DVG2 - 04
22
public class test10
{
public static int f ( int z, int n ) throws Ausnahme
{
if ( n == 0 )
{
throw new Ausnahme();
}
return z/n;
}
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
DVG2 - 04
23
 Für eigene Ausnahmen sollten die Konstruktoren definiert werden, da
nur der „leere Konstruktor“ automatisch erzeugt wird.
public class Ausnahme extends Exception
{
Ausname() { super() }
Ausnahme(String message) { super(message) }
}
 Bei dieser Form kann eine Nachrichtentext den Fehler genauer
erläutern bzw. lokalisieren.
DVG2 - 04
24
Beispiel : Skalarprodukt
static double ScalarProduct(double [] x, double [] y)
{
double sp=0.0;
for (int i=0;i<x.length;i++) sp+=x[i]*y[i];
return sp;
}
DVG2 - 04
25
Zusammenfassung
Aktivieren von Ausnahmen
throw new NameDerAusnahme ("Fehlermeldung",...);
DVG2 - 04
26
static double ScalarProduct(double [] x, double [] y)
{
if (x==null) throw
new NullPointerException("erster Parameter null");
if (y==null) throw
new NullPointerException("zweiter Parameter null");
double sp=0.0;
for (int i=0;i<x.length;i++) sp+=x[i]*y[i];
return sp;
}
DVG2 - 04
27
Definition von Ausnahmen
[public] class NameDerAusnahme extends Exception
{
NameDerAusnahme()
{ super(); }
NameDerAusnahme(String message)
{ super(message); }
[weitere Konstruktoren, Attribute, Methoden]
}
DVG2 - 04
28
Beispiel : eigene Ausnahme
public class DimensionException extends Exception
{
DimensionException()
{
super();
}
DimensionException(String message)
{
super(message);
}
}
DVG2 - 04
29
static double ScalarProduct(double [] x, double [] y)
{
if (x==null) throw
new NullPointerException("erster Parameter null");
if (y==null) throw
new NullPointerException("zweiter Parameter null");
if (x.length != y.length)
throw new DimensionException (
"Ungleiche Dimension der Felder im Skalarprodukt");
double sp=0.0;
for (int i=0;i<x.length;i++) sp+=x[i]*y[i];
return sp;
}
DVG2 - 04
30
Weiterreichen von Ausnahmen
... NamederMethode (...) throws NameDerAusnahme1,
NameDerAusnahme2,..., NameDerAusnahmeN
DVG2 - 04
31
static double ScalarProduct(double [] x, double [] y)
throws DimensionException
{
if (x==null) throw
new NullPointerException("erster Parameter null");
if (y==null) throw
new NullPointerException("zweiter Parameter null");
if (x.length != y.length)
throw new DimensionException (
"Ungleiche Dimension der Felder im Skalarprodukt");
double sp=0.0;
for (int i=0;i<x.length;i++) sp+=x[i]*y[i];
return sp;
}
DVG2 - 04
32
Beispiel : Matrix x Vektor
static double [] MatrixVektor(double[][]A, double[]x)
{
double [] y = new double[A.length];
for (int i=0;i<y.length;i++)
{
y[i]=ScalarProduct(A[i],x);
}
return y;
}
DVG2 - 04
33
Abfangen von Ausnahmen
try {
// Anweisungen im try-Block
}
catch (NameDerAusnahme1 e) {
// Anweisungen im ersten catch-Block
}
...
catch (NameDerAusnahmeN e) {
// Anweisungen im N-ten catch-Block
}
finally {
// Anweisungen im finally-Block
}
DVG2 - 04
34
Beispiel : Matrix x Vektor
static double [] MatrixVektor(double[][]A, double[]x)
throws DimensionException
{
if (A==null) throw
new NullPointerException("erster Parameter null");
if (x==null) throw
new NullPointerException("zweiter Parameter null");
double [] y = new double[A.length];
for (int i=0;i<y.length;i++)
{
if (A[i]==null) throw
new NullPointerException("Matrixzeile "+i+" gleich null");
try { y[i]=ScalarProduct(A[i],x); }
catch (DimensionException e)
{throw new DimensionException ("Falsche Dimension in Zeile “
+i);}
}
return y;
}
DVG2 - 04
35
static double ScalarProduct(double [] x, double [] y)
throws DimensionError
{
try
{
if (x.length != y.length) throw new
DimensionError("Ungleiche Dimension der Felder im Skalarprodukt");
double sp=0.0;
for (int i=0;i<x.length;i++) sp+=x[i]*y[i];
return sp;
}
catch (NullPointerException e)
{
if(x==null)throw new NullPointerException("erster Parameter null");
if(y==null)throw new NullPointerException("zweiter Parameter null");
return 0;
}
}
DVG2 - 04
36
static double [] MatrixVektor(double[][]A, double[]x)
throws DimensionError
{
int i = 0;
try
{
double [] y = new double[A.length];
for (i=0;i<y.length;i++) y[i]=ScalarProduct(A[i],x);
return y;
}
DVG2 - 04
37
catch (DimensionException e)
{
throw new DimensionException
("Falsche Dimension in Zeile "+i);
}
catch (NullPointerException e)
{
if (A==null)
throw new NullPointerException("erster Parameter null");
if (x==null)
throw new NullPointerException("zweiter Parameter null");
if (A[i]==null)
throw new NullPointerException(
"Matrixzeile "+i+" gleich null");
}
return null;
}
DVG2 - 04
38
Herunterladen