Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


6.1

Das Konzept


Das Konzept der Zusicherungen (Assertions) stammt aus dem Gebiet der Qualitätssicherung und Software-Verifikation. Eine Zusicherung dient dazu, an einer bestimmten Stelle in einem Programm sicherzustellen, dass eine Bedingung immer erfüllt ist (z. B. »Variable x ist an dieser Stelle größer als Null«). Durch die Formulierung und Prüfung dieser Bedingungen kann gewährleistet werden, dass sich ein Programm an einer bestimmten Stelle korrekt verhält und nicht in einem unbestimmten oder nicht erwarteten Zustand ist.

Generell werden drei Arten von Zusicherungen unterschieden:

Seit [1.4]Version 1.4 werden Zusicherungen auch in Java unterstützt. Eine Zusicherung besteht aus dem neuen Schlüsselwort assert gefolgt von einem beliebigen Ausdruck mit dem Ergebnistyp boolean.
  assert <Bedingung>;
Optional kann dem logischen Ausdruck durch einen Doppelpunkt getrennt ein zweiter Ausdruck mit einem beliebigen Ergebnistyp angehängt werden:
  assert <Bedingung> : <Ausdruck>;
Dieser Ausdruck dient als Fehlermeldung und wird nur dann ausgewertet, wenn die Zusicherung verletzt wird, der erste logische Ausdruck also false ergibt. Die folgenden Zeilen zeigen Beispiele für assert-Anweisungen:
  int x;
  Character c;
  ...
  assert (x > 0);
  // auch Methodenaufrufe sind möglich
  assert (c.isUpperCase());
  // Methodenaufruf mit Ausdruck für Fehlermeldung
  assert (c.isUpperCase()) : "c is not upper case: "+c;
Wenn eine Zusicherung verletzt wird, wird ein AssertionError ausgelöst. Sofern der zweite Ausdruck in der assert-Anweisung vorhanden ist, wird sein Ergebnis einem entsprechenden Konstruktor von AssertionError übergeben, als String konvertiert und so als Meldung für die Ursache der Verletzung gespeichert.

Rein prinzipiell lassen sich derlei Prüfungen auch mit if-Anweisungen realisieren. Diese sind aber zum einen nicht standardisiert und zum anderen wird die if-Bedingung ohne weitere Maßnahmen immer abgeprüft. assert-Anweisungen dagegen werden nur dann ausgewertet, wenn die Auswertung explizit aktiviert wird - entweder per Kommandozeilen-Option beim Interpreter oder aus dem Programm selbst heraus.

Zusicherungen sollten in Java hauptsächlich für Nachbedingungen und Invarianten verwendet werden. Für Vorbedingungen, insbesondere für Werteüberprüfungen von Methodenparametern, sollten sie nur in Methoden verwendet werden, die nicht zur öffentlichen Schnittstelle der Klasse gehören. In public-Methoden ist dagegen der übliche Weg normaler Werteprüfung mit if-Anweisungen in Verbindung mit der Auslösung einer IllegalArgumentException eindeutig vorzuziehen und zwar aus zwei Gründen: Im folgenden Beispiel werden Zusicherungen für eine Invariante in einer for-Schleife sowie für zwei Nachbedingungen verwendet. Die Gültigkeit der Parameter wird dagegen konventionell geprüft und bei Verletzungen eine IllegalArgumentException ausgelöst. Die gezeigte Methode subArray() liefert einen Bereich eines übergebenen char-Arrays zurück. Dabei muss sichergestellt werden, dass keine Indizierungsfehler auftreten.
  public static char[] subArray(char[] array, int start, int end) {
    if (array ==  null)
      throw new IllegalArgumentException("array reference is null");
    if (start < 0)
      throw new IllegalArgumentException("start is < 0");
    if (end > array.length)
      throw new IllegalArgumentException("end > length");
    if (start > end)
      throw new IllegalArgumentException("start > end");

    char[] result = new char[end-start];
    for(int i = start; i < 10; i++) {
      assert (i >= 0) && (i < result.length) : "i out of bounds: "+i;
      result[i] = array[i];
    }
    assert (result != null);
    assert (result.length == (end-start));
    return result;
  }

Wie bereits erwähnt, werden assert-Anweisungen nur dann ausgewertet, wenn die Prüfung von Zusicherungen ausdrücklich aktiviert ist. Standardmäßig sind Zusicherungen deaktiviert. Aufgrund dieser Tatsache sollten die Ausdrücke in assert-Anweisungen keinerlei Seiteneffekte enthalten, da sonst das Programmverhalten davon abhängt, ob Zusicherungen aktiviert sind oder nicht, wie das folgende Beispiel zeigt:
  assert (i++ < limit);
In dieser Zeile wird i nur dann inkrementiert, wenn Zusicherungen aktiviert sind. Ansonsten wird die Anweisung nicht ausgeführt und der Wert bleibt unverändert. Somit hängt das Verhalten des Programms davon ab, ob Zusicherungen aktiviert sind oder nicht.

Andererseits kann man sich diese Abhängigkeit auch zunutze machen, um im Programm festzustellen, ob Zusicherungen aktiviert sind, beispielsweise um während der Entwicklung eine Warnung auszugeben, falls dies nicht der Fall ist:
  static boolean assertionsActive = false;

  ...
  assert (assertionsActive = true);
  if (!assertionsActive)
    System.err.println("Warning: Assertions not enabled!");
Die Zuweisung von true in der assert-Anweisung wird nur dann ausgeführt, wenn Zusicherungen aktiviert sind. Daher kann man am Wert der Variable sehen, ob Zusicherungen aktiviert sind.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.