Softwareentwicklung 2 Assertions Wieland Schwinger ([email protected]) Lernziehle Assertions Wozu ? Ein- und Ausschalten Unterschiede zu Exceptions Softwareentwicklung 2 Folie 2 Was sind Assertions Assertions sind Zusicherungen Verletzung der Zusicherung führt zu java.lang.AssertionError Assertions sind boolsche Ausdrücke die mit assert eingeleitet werden Die Überprüfung von Assertions kann mit "java -enableassertions" beim Ausführen ein- und ausgeschaltet werden. Softwareentwicklung 2 Folie 3 Einfaches Assertions Beispiel /** * Sets the refresh rate. * * @param rate refresh rate, in frames per second. * @throws IllegalArgumentException if rate <= 0 or * rate > MAX_REFRESH_RATE. */ public void setRefreshRate(int rate) { // Enforse specified pre-condition in public method if (rate <= 0 || rate > MAX_REFRESH_RATE) throw new IllegalArgumentException("Illegal rate:" + rate); setRefreshInterval(1000/rate); } private void setRefreshInterval(int interval) { // confirm adherence to pre-condition in non-public method assert interval>0 && interval<=1000/MAX_REFRESH_RATE : "Interval is " + interval); // set the refresh rate.... } } Softwareentwicklung 2 Folie 4 Beispiel Kehrwert public class TestAssertions { private double val; public TestAssertions(double x) {this.val = x;} public double getVal() {return this.val;} double kehrwert() { assert this.val > 0:"Nur werte <> 0 zulässig"; return (double)(1/val); } } // end class TestAssertions public class TestAssertionMain { public static void main(String args[]) { TestAssertions t = new TestAssertions(0.0); System.out.println(" Wert: " + t.getVal()); System.out.println(" Kehrwert : " + t.kehrwert() ); } } Softwareentwicklung 2 Folie 5 Beispiel Kehrwert - Was passiert ? Ohne Assertion: double kehrwert() { return (double)(1/val); } Wert: 0.0 Kehrwert : Infinity Mit Assertion-Statement: double kehrwert() { assert this.val > 0 : "Nur werte <> 0 zulässig"; return (double)(1/val); } Wert: 0.0 Kehrwert : Infinity Mit Assertions enabled: ...java -enableassertions MeinJavaFile.java Softwareentwicklung 2 Wert: 0.0 Exception in thread "main" java.lang.AssertionError: Nur werte <> 0 zulässig at TestAssertions.kehrwert(TestAssertions.java:23) at TestAssertionMain.main(TestAssertionMain.java:18) Folie 6 Softwareentwicklung 2 Einschlaten von Assertions ...java -enableassertions MeinJavaFile.java Folie 7 Anwendung von Assertions Flexible Laufzeitprüfung von pre- und postconditions sowie Invarianten. Diese werden nur geprüft, wenn es beim Aufruf auch verlangt wurde Softwareentwicklung 2 Folie 8 Anwendung von Assertions Immer dann, wenn durch einen Kommentar ein Zustand vermerkt ist. if (i % 3 == 0) { ... } else if (i % 3 == 1) { ... } else { //we know (i % 3 == 2) ... } switch (month) { case 1: … case 2: … … case 12: … default: // never reached! } Softwareentwicklung 2 if (i % 3 == 0) { ... } else if (i % 3 == 1) { ... } else { assert i % 3 == 2 : i; ... switch (month) { case 1: … case 2: … … case 12: … default: assert false; } Folie 9 Wo sollen Asserts nicht verwendet werden! Nicht zur Prüfung von Übergabeparametern in public-Methoden! So NICHT: public Employee(String name, double salary) { assert name != null : "invalid name"; assert salary >= 0 : "invalid salary"; Weil hier ev. nicht zulässige Werte gesetzt werden würden, falls Überprüfung abgedreht wird this.name = name; this.salary = salary; } So schon: public double getTotalSalary() { Weil hier nur auf Werte zugegriffen wird, die von einer anderen Methode (setter) richtig gesetzt werden sollten (dh. man kann eh nichts mehr machen). Dh. ist diese Annahme verletzt, dann gibt es einen Fehler bei der internen Koordination der Methoden/Aufgaben assert getBoss() == null || salary < getBoss().getTotalSalary() * 0.8 : "salary too high"; return salary; } Nicht zur Berechungen/Verarbeitungen, die das Programm in weiterer Folge für sein funktionieren benötigt, da asserts ev. ausgeschaltet werden und diese Berechnungen/Verarbeitungen dann nicht statt finden Softwareentwicklung 2 Folie 10