Exception Handling in Java
Seminar aus
Softwareentwicklung
Norbert Wiener
Ziele von Exception Handling
Programme robuster machen gegen:
• fehlerhafte Eingaben
• Gerätefehler (Defekte, Platte voll, ...)
• Programmierfehler (z.B. Division durch 0)
Trennung zwischen Algorithmus und
Fehlerbehandlung
Fehlerbehandlung durch Compiler überprüfbar
machen
Auslösen von Exception
explizite Ausnahmen: „throw“ Anweisung im Code.
setPassword(String pw) {
......
}
if(pw.length() < 5) throw new Exception(„mind. 5 Zeichen“);
.......
implizite Ausnahmen durch die JVM
- Divison durch 0
=> ArithmeticException
- Zugriff über null-Ref.
=> NullPointerException
- Ungültige Konvertierung => ClassCastException
int intDiv (int i, int j) {
return i/j;
}
try-catch-finally Syntax
try {
Anweisungen;
} catch (Ausnahme1 a1) {
Fehlerbehandlung1;
} catch (Ausnahme2 a2) {
Fehlerbehandlung2;
} finally {
Aufräumen;
}
Nach einem try-Block
muss mindestens ein
catch-Block folgen!
Der finally-Block ist
optional
Bei mehreren catch-Blöcken beginnt die
Suche der Ausnahmenbehandlung von
oben nach unten.
Beispiel
class Catch{
public static void main(String[] args){
try{
int i = Integer.parseInt(args[0]);
System.out.print("i= "+i);
}catch(ArrayIndexOutOfBoundsException e){
System.out.print("Parameter vergessen!");
}catch(NumberFormatException e){
System.out.print(" kein int-Wert!");
}finally{
System.out.println(" finally!");
}
}
}
Catch 123
i= 123 finally!
Catch xy
kein int-Wert! finally!
Catch
Parameter vergessen! finally!
Finally wird immer
ausgeführt!
Ausnahme-Klasse definieren
class MyException extends Exception{
}
class MyException extends Exception{
public MyException() {
super();
}
public MyException(String msg) {
super(msg);
}
}
Eigener Exceptiontyp
(indirekt) von
Throwable ableiten.
Konstuktor ohne
Parameter
Konstruktor mit
Fehlermeldung
Die throws-Klausel
setPassword(String pw) {
try{
if(pw.length() < 5){
throw new Exception(„Fehler“);
}
}catch(Exception e){
Ausnahme behandeln!
}
}
Weitergabe der Exception an die aufrufende Methode
Try{
setPassword(pw);
}catch(Exception e){
Ausnahme behandeln!
}
static setPassword(String pw)
throws Exception {
if(pw.length() < 5){
throw new Exception(„Fehler“);
}.......
}
throws Beispiel
..Main(...){
......
try{
A(x);
}catch(Exc1 e){
..print("Main");
}
........
C(int x)
........
........
A(int x)
B(int x)
throws Exc1, Exc2 ,Exc3 {
throws Exc1{
throws Exc1, Exc2{
try{
try{
if(x==1){
try{
B(x);
throw new Exc1("F.");
C(x);
}catch(Exc2 e){
}catch(Exc3 e){
...println("A");
...println("B");
}finally{
}else if(x==2){
throw new Exc2();
}else if(x==3){
}finally{
..println("finA")
throw new Exc3();
...println("finB");
}
}else{
}
}
throw new Exc4();
}
}
x=1
x=2
x=3
x=4
finB
finB
B
C
finA
A
finB
finB
Main
finA
finA
finA
}catch(Exc4 e){
....println("C");
}
}
Debugging von Ausnahmen
class Test{
static int x =1;
e.getMessage()
e.printStackTrace()
public static void main(String args[]) {
try{
A a= new A(x);
}catch(Exc1 e){
System.out.println("Main");
System.out.println(e.getMessage());
e.printStackTrace();
}
}
}
finB
finA
Main
Fehler!
Exc1: Fehler!
at C.<init>(C.java:6)
at B.<init>(B.java:4)
at A.<init>(A.java:4)
at Test.main(Test.java:6)
Klassenhierarchie
Throwable
Error
Exception
VirtualMachineError
LinkageError
RuntimeException
IOException
OutOfMemoryError
NoSuchFieldError
NullpointerException
FileNotFoundException
unchecked
checked
Die Error-Klasse
VirtualMachineError
InternalError
OutOfMemoryError
StackOverflowError
UnknownError
LinkageError
NoSuchMethodError
NoSuchFieldError
AbstraktMethodError
ThreadDeath
Ausnahmen des
Typs Error sind
nicht vernünftig
zu behandeln.
Die Exception Klasse
IOException
FileNotFoundException
SocketException
EOFException
RemouteException
UnknownHostException
InterruptedException
NoSuchFieldException
ClassNotFoundException
NoSuchMethodException
Diese Exception
müssen behandelt
werden!
(ausgenommen
RuntimeException)
Exception auf ByteCode Ebene
void f() {
try {
throw new Exception();
} catch (Exception e) {
System.out.println(e);
}
}
0
3
4
7
8
9
12
13
16
new #2 <Class Exception>
dup
invokespecial <init>
athrow
astore_1
getstatic out:System
aload_1
invokevirtual println
return
Exception e;
e = new Exception();
throw e;
Adr.-> Exception
Adr.-> Exception
Operanden-Stack
Objekt im Speicher allokieren
Objektreferenz auf OperantenStack
Referenzadresse wird dupliziert
Konstruktor wird ausgeführt
Exception Table:
From
0
To
Target
8
8
Type
Exception
Beispiel
static int remainder(int dividend, int divisor)
throws OverflowException, DivideByZeroException
{
if ((dividend == Integer.MIN_VALUE) &&
(divisor == -1)) {
throw new OverflowException();
}
try {
return dividend % divisor;
}
catch (ArithmeticException e) {
throw new DivideByZeroException();
}
}
Exception Handling
wird an die
Vorgängermethode
delegiert!
Beispiel
static int remainder(int dividend, int divisor)
throws OverflowException, DivideByZeroException {
if ((dividend == Integer.MIN_VALUE) &&
(divisor == -1)) {
throw new OverflowException();
}
try {
return dividend % divisor;
}
catch (ArithmeticException e) {
throw new DivideByZeroException();
}
}
Exception Table:
From
To
Target
19
23
23
Type
ArithmeticException
0
1
3
6
7
8
iload_0
ldc #1 <Integer - 2147483648>
if_icmpne 19
iload_1
iconst_m1
if_icmpne 19
11 new #4 <Class
OverflowException>
14 dup
15 invokespecial #10 <Method
OverflowException()>
18 athrow
19
20
21
22
23
24
27
28
iload_0
iload_1
irem
ireturn
pop
new #2 <Class DivideByZeroE.>
dup
invokespecial #9 <Method
DivideByZeroException()>
31 athrow
Danke für
die Aufmerksamkeit