Assertions – Java Programme zuverlässiger und besser lesbar machen mit assert-Anweisungen

In diesem Beitrag lernen wir die assert-Anweisung von Java kennen.

Mit Assertions können vom Programmierer logische Behauptungen aufgestellt werden, von denen er ausgeht diese seien wahr. Solange das Programm korrekt funktioniert, bleiben die assert-Anweisungen unbemerkt.

Sobald mit Hilfe einer Assertion aber ein Programmfehler aufgedeckt wird, wird eine Ausnahme des Typs AssertError ausgelöst.

In Java werden assert-Anweisungen immer dann eingesetzt, wenn man den Zustand des Programms überprüfen und diesen durch bestimmte Annahmen verifizieren möchte.

Die Syntax von assert-Anweisungen:

assert Testausdruck;

assert Testausdruck : Meldungsausdruck;

Die Syntax von assert-Anweisungen ist sehr kurz und leicht lesbar.

Der Testausdruck muss vom Datentyp boolean sein. Der Meldungsausdruck ist optional und kann von beliebigem Datentyp sein.

Wird der Meldungsausdruck mit angegeben, wird dieser im Fehlerfall an den Konstruktor von AssertError übergeben und als Meldungstext für das erstellte Fehlerobjekt verwendet.

Möchte man bspw. überprüfen, ob eine Variable negativ ist, dann lautet die assert-Anweisung wie folgt: assert x < 0;.

In dem oberen Codebeispiel überprüft das Programm die Bedingung. Ist diese wahr, wird das Programm normal weiter ausgeführt und der Benutzer nimmt davon keine Kenntnis. Ist aber die Bedingung nicht wahr, wird eine AssertError Ausnahme ausgelöst.

plhq_teaser_hbox_gelb_fotolia_RA Studio_46292813

Unser großes
Android Online-Kurs
Gesamtpaket



Weitere Infos

Diese Überprüfung hätte man auch mit einer if-Anweisung vornehmen können. Dann hätte man aber nicht auf den ersten Blick gesehen, dass es sich bei dieser Überprüfung um eine Verifizierung des Programmzustands handelt, da if-Anweisungen vorwiegend zur Steuerung des Programmablaufs eingesetzt werden.

Vorteile von Assertions gegenüber if-Anweisungen:

  • Besser lesbarer und kürzerer Programmcode
  • Sofortiges Erkennen von Korrektheits-Überprüfungen
  • Zuverlässigere Programme bei so gut wie keiner Verschlechterung des Laufzeitverhaltens, durch Abschalten der Assertions
  • Einfache Textausgabe im Fehlerfall

Kompatibilität der assert-Anweisung

Durch die Verwendung von assert-Anweisungen können Kompatibilitätsprobleme entstehen. In Java wurden Assertions erst mit der Version 1.4 des JDK eingeführt.

Um Assertions fehlerfrei einsetzen zu können, muss ein JDK 1.4 Compiler verwendet werden und auf allen Zielsystemen mindestens ein Java 1.4 Laufzeitsystem vorhanden sein.

Wann sollten assert-Anweisungen verwendet werden?

  1. Kontrolle von nicht erreichbaren Zweigen in if-, else- und case-Anweisungen. Es ist besser dort eine assert-Anweisung zu verwenden, anstatt einen Kommentar "Kann nicht erreicht werden!" zu platzieren.
  2. Kontrolle von Schleifenbedingungen die immer erfüllt sein müssen (sog. Invarianten), bspw. dass ein Zähler nicht negativ wird. Die assert-Anweisung sollte gerade bei komplexen Schleifen eingesetzt werden, um die Korrektheit zu prüfen und sicherzustellen.
  3. Kontrolle von Parametern vor der Übergabe an nichtöffentliche Methoden und von Bedingungen, die am Ende einer Methode immer erfüllt sein müssen (Postconditions).

Programmbeispiel - So werden Assertions in Java verwendet

In dem folgenden Beispielprogramm werden assert-Anweisungen verwendet. Mit den Assertions soll die Korrektheit des Programmzustands sichergestellt werden.

Wir werden das Programm einmal mit aktivierten Assertions ausführen und einmal mit abgeschalteten assert-Anweisungen.

In die unteren Beispielanwendung wurde absichtlich ein Programmfehler (Zeile 21) eingebaut.

Beispielanwendung die assert-Anweisung mit Fehler.

/*
* Beispielanwendung die assert-Anweisung mit Fehler
*/

public class Assertions{
 public static void main(String[] args) {

   int counter = 11;
   System.out.println();
   
   while (true)
   {

     counter--;

     assert counter >= 0 : "\nProgrammfehler - Counter ist negativ!";

     if (counter == 0)
     {
        System.out.println("\nStart!\n");
        // break;
     }

     if (counter > 0)
     {
        System.out.println("Noch " + counter + " Sekunden bis zum Start.");
     }

   }

 }
 
}

Da die break-Anweisung in Zeile 21 auskommentiert ist, wird die while-Scheife niemals beendet und läuft endlos.

Mit der assert-Anweisung in Zeile 16 überprüfen wir die Schleifenbedingung, die immer erfüllt sein muss, nämlich dass der counter nicht negativ werden darf.

Wir haben nun die Möglichkeit die Java-Anwendung in der Kommandozeile mit aktivierten oder deaktivierten Assertions zu starten:

Assertions aktivieren: java -enableassertions oder java -ea.
Assertions deaktivieren: java - disableassertions oder java -da.

Starten wir nun die Java-Anwendung zuerst mit deaktivierten Assertions. In der folgenden Abbildung ist die resultierende Kommandozeilenausgabe dargestellt:

Java Assertions deaktiviert

Java Assertions - Anwendung mit deaktivierten Assertions gestartet

Da die while-Schleife niemals beendet wird, läuft das Programm nicht korrekt.

Wenn wir nun die Java-Anwendung mit aktivierten Assertions starten, können wir uns diesen fehlerhaften Programmzustand anzeigen lassen und anschließend das Programm an der fehlerhaften Stelle korrigieren.

Führen wir nun die Java-Anwendung mit aktivierten Assertions aus. In der folgenden Abbildung ist die resultierende Kommandozeilenausgabe dargestellt:

Java Assertions aktiviert

Java Assertions - Anwendung mit aktivierten Assertions gestartet

Nachdem der Fehler mit der Endlosschleife bereinigt wurde und in Zeile 21 eine break-Anweisung eingeführt wurde, starten wir das Programm erneut, diesmal mit aktivierten Assertions.

In der folgenden Abbildung ist die resultierende Kommandozeilenausgabe dargestellt:

Java Assertions aktiviert korrekt

Java Assertions - Korrigierte Anwendung mit aktivierten Assertions gestartet

Da nun die Korrektheit der Java-Anwendung sichergestellt ist, können die Assertions mit der Kommandozeilenoption java -da deaktiviert werden. Dadurch läuft das Programm ohne Verschlechterung des Laufzeitverhaltens.

Die verwendeten assert-Anweisungen müssen dazu nicht auskommentiert werden.


Comments 3

  1. Sehr schön erklärt, aber eine Frage habe ich noch:

    „1.Kontrolle von nicht erreichbaren Zweigen in if-, else- und case-Anweisungen. Es ist besser dort eine assert-Anweisung zu verwenden, anstatt einen Kommentar „Kann nicht erreicht werden!“ zu platzieren.“

    Inwiefern hilft mir da die Assertion wenn der Zweig und damit die Assertion doch nie erreicht wird?

    1. Post
      Author

      Hallo MoSees,

      mit der Assertion kann kontrolliert werden, ob der theoretisch nicht erreichbare Zweig auch in der Praxis wirklich nicht erreicht wird. Es könnte ja sein, dass die Programmlogik fehlerhaft ist und der Zweig doch erreichbar ist. Dann könnte man sich mit Hilfe einer Assertion darüber informieren lassen.

      Viele Grüße, Chris

  2. Pingback: Verzweigungen in Java: Die if-else-Anweisung, switch-Anweisung und assert-Anweisung -

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht.