1. 10.06.2012
1
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
Eine Ausnahme (engl. Exception) ist ein Ereignis, das
während der Ausführung des Programms auftritt, und den
normalen Fluss der Befehle unterbricht.
Beispiele für Ausnahmesituationen:
• bei Berechnungen Division durch Null
• Mangel an Speicherplatz
• Zugriff auf Array-Elemente über die Obergrenze hinaus
• Schreib-/Lesefehler bei Ein- und Ausgabeoperationen
– Diskette defekt
– Netzwerkverbindung zusammengebrochen
– Festplatte voll
– zu öffnende Datei nicht vorhanden usw.
Java unterstützt explizite Ausnahmebehandlung:
systematische und übersichtliche Trennung von normalem und
fehlerbehandelndem Code
Methoden können angeben, ob sie bzw. der in ihnen
enthaltene Programmcode Ausnahmesituationen
feststellen bzw. auslösen können.
Im Falle einer Ausnahme wird ein sog. Exception‐Objekt
erzeugt und an den Aufrufer der Methode übergeben
Eine Exception kann als ein durch eine Datenstruktur
repräsentiertes Ereignis angesehen werden
Im Falle einer Ausnahmesituation wird diese mit Hilfe der
Datenstruktur der Exception gemeldet.
Exceptions sind in Java als Klasse realisiert und
zwar als Unterklasse der Klasse Throwable.
Throwable
(from lang)
Exception
(from lang)
2. 10.06.2012
2
Ausschnitt aus der Klassenhierarchie
unterhalb der Klasse Exception:
Exception
(from lang)
ArrayIndexOutOfBoundsException
(fromlang)
ArithmeticException
(from lang)
IOException
(fromio)
FileNotFoundException
(fromio)
Ausnahmebehandlung wird in Java über die try‐Anweisung realisiert, die
aus einem try‐Block, einem oder mehreren catch‐Konstrukten und
optional einem finally‐Konstrukt bestehen muss.
Syntax:
try {
... }
catch (Exceptiontyp1 name1) {
... }
catch (Exceptiontyp2 name2) {
... }
finally {
... }
Hier steht der
Programmcode, in dem
Fehler auftreten können Hier werden
Fehler der Art
Exceptiontyp1
abgefangen
Hier werden
Fehler der Art
Exceptiontyp2
abgefangen
Wird durchlaufen, egal
ob ein Fehler auftrat
oder nicht.
Machen Sie folgendes Programm mittels
try {...} catch (Exception e) {...} absturzsicher!
class Ereignis1 {
public static void main (String args[]) {
int a;
int b = 0;
a = 10/b;
System.out.println("Programmende wurde erreicht!");
}
}
Abfangen einer „allgemeinen“ Exception:
class Ereignis1 {
public static void main (String args[]) {
int a;
int b = 0;
try {
a = 10/b;
}
catch (Exception e) {
System.out.println("Fehler aufgetreten: "+e.getMessage());
}
System.out.println("Programmende wurde erreicht!");
}
}
3. 10.06.2012
3
Eine Methode muss Exceptions, die sie auslöst, nicht selber abfangen;
dies kann auch in einer sie aufrufenden Methode erfolgen.
Exceptions werden auf diese Weise durch die Methoden‐Aufrufkette quasi
„nach oben“ propagiert.
Fängt eine Methode Exceptions nicht selbst ab, sondern leitet sie weiter, so
muss die Exception bei der Definition der Methode angegeben werden.
Anderenfalls resultiert ein Kompilierfehler.
Beispiel:
Rückgabetyp Methodenname (Parameter) throws Exceptionklasse {
. . .
}
wird eine Exception auf oberster Ebene weitergereicht, bricht das
Programm mit einer sog. Runtime‐Exception ab
Trennung des Fehlerbehandlungscodes vom normalen Programm.
Höhere Absturzsicherheit von Programmen dadurch, dass Methoden
erzwingen können, dass Aufrufer eine Fehlerbehandlung vorsehen
müssen
Aufgrund der Exception‐Klassenhierarchie können Fehler entweder
gruppiert oder auch differenziert behandelt werden
Weiterreichen von Fehlern über verschachtelte Methodenaufrufe hinweg
• ohne Exceptions
void dateilesen() {
öffnen();
if(öffnenok) {
dateiInhaltlesen();
if (ok){
interpretieren;
...
} else fehler;
} else fehler;
}
• mit Exceptions
try{
öffnen();
dateiInhaltlesen();
interpretieren();
} catch (Exception e) {
fehlerbehandlung;
}
explizite Ausnahmen: „throw“ Anweisung im Code.
implizite Ausnahmen durch die JVM
‐ Divison durch 0 => ArithmeticException
‐ Zugriff über null‐Ref. => NullPointerException
‐ Ungültige Konvertierung => ClassCastException
setPassword(String pw) {
......
if(pw.length() < 5) throw new Exception(„mind. 5 Zeichen“);
.......
}
int intDiv (int i, int j) {
return i/j;
}
4. 10.06.2012
4
try {
Anweisungen;
}
catch (Ausnahme1 a1) {
Fehlerbehandlung1;
}
catch (Ausnahme2 a2) {
Fehlerbehandlung2;
}
finally {
Aufräumen;
}
Der finally-Block ist
optional
Nach einem try-Block
muss mindestens ein
catch-Block folgen!
Bei mehreren catch-Blöcken beginnt die
Suche der Ausnahmenbehandlung von
oben nach unten.
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!
class MyException extends Exception{
public MyException() {
super();
}
public MyException(String msg) {
super(msg);
}
}
Konstuktor ohne
Parameter
Konstruktor mit
Fehlermeldung
class MyException extends Exception{
}
Eigener Exceptiontyp
(indirekt) von
Throwable ableiten.
Weitergabe der Exception an die aufrufende Methode
setPassword(String pw) {
try{
if(pw.length() < 5){
throw new Exception(„Fehler“);
}
}catch(Exception e){
Ausnahme behandeln!
}
}
static setPassword(String pw)
throws Exception {
if(pw.length() < 5){
throw new Exception(„Fehler“);
}.......
}
Try{
setPassword(pw);
}catch(Exception e){
Ausnahme behandeln!
}
6. 10.06.2012
6
• Realisierung ist noch nicht bekannt, aber man weiß schon,
was realisiert werden soll.
• Man will mehrere auch konkurrierende Realisierungen
zulassen und dabei sicherstellen, daß gewisse
Eigenschaften gewährleistet werden.
• Die grundlegenden Eigenschaften werden durch
Signaturen festgelegt.
• Die Signatur einer Methode legt ihr Eingabe‐
/Ausgabeverhalten fest, also die Typen der
Eingabeparameter und den Rückgabewert.
extends ist das Schlüsselwort für Interfacevererbung:
interface UnterInterface extends OberInterface
{
Interfacebody
}
Klassen erben von Interfaces über das Schlüsselwort
implements
interface I {
Methodendeklarationen;
}
interface I {
Methodendeklarationen;
}
Klassen können von einem oder mehreren Interfaces und auch
zusätzlich von einer Oberklasse erben:
class NameUnterklasse extends
NameOberklasse implements Interface1,
Interface2, ... {
...
}
Werden von einer Klasse nicht alle Methoden des Interfaces
implementiert, muß sie mit abstract gekennzeichnet werden
Analog zum Erben von Oberklassen ist Polymorphie möglich
Die Supertypen einer Klasse A sind
die Klasse B, von der A erbt,
die Interfaces, die A implementiert,
und die Supertypen, dieser Klasse und Interfaces.
Alle Interface‐Methoden sind implizit public und abstract.
Begründung: public weil alle realisierenden Klassen wissen
müssen, was sie realisieren sollen, abstract weil das das
Merkmal von Interfaces ist.
Alle Attribute sind implizit public, static und final
Begründung: Es kann nur um Konstanten gehen, die immer
gleich verwendet werden (also final). Diese braucht man dann
nicht pro Objekt, sondern nur pro Klasse (also static).
7. 10.06.2012
7
public interface Kalorien {
public double lesenKalorien();
}
Jede Klasse, die eine Methode lesenKalorien() enthält, kann das
Interface implementieren:
public class SchokoKeks extends Keks implements Kalorien {
private double kal;
public double lesenKalorien() {
return kal;
}
// .. weitere Methoden von SchokoKeks
}
Andere Klassen können Referenzen auf
Objekte der Klasse Interface erzeugen und
diesen Objekte der Klasse SchokoKeks
zuweisen (=Polymorphismus):
public class A {
Kalorien sKeks = new SchokoKeks();
System.out.println(skeks.lesenKalorien());
...
}