4. Einige wichtige Java-Dinge • • • • • • Ausnahmebehandlung Enumeration Daten speichern und laden Dokumentation Umgang mit externen Paketen Model View Controller Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 90 Ausnahmenarten • Alle neuen Sprachen erlauben Exception Handling • Ausnahme werfen, wenn nicht erwarte Situation auftritt • Programmierfehler (z. B. NullPointerException), führt zum Programmabbruch; nie behandeln, nur loggen • Java: • Exceptions, die von RuntimeExeption erben, müssen nicht behandelt werden (unchecked Exception) • Andere (checked) Exceptions müssen behandelt werden; nach außen geben (throws) oder behandeln (try-catch-finally) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 91 Ausnahmenbehandlung • eigene Exception-Klasse erbt von Exception public class Nicht42Exception extends Exception { public Nicht42Exception(String nachricht){ super(nachricht); } } • Variante: Nutzung vorhandener Exception, typisch throw new IllegalArgumentException("Grund"); • try-catch-finally (mehrere catch möglich, finally optional): – keine Exception in try, dann in finally weitermachen – Exception: catches abarbeiten, wenn treffend, dann diesen catch-Block, dann in finally (und danach weiter) – Exeception: kein catch, dann finally, dann an aufrufende Methode weiterleiten (wieder wie beschrieben) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 92 Beispiel: Ausnahmenbehandlung (1/2) public class Rechner { public void analyse(int x, int y) throws Nicht42Exception{ if (x==6 && y==9) throw new IllegalArgumentException("nicht beantwortbar"); else if (x*y==42) throw new Nicht42Exception("nich 42"); } public int mal(int x, int y) throws Nicht42Exception{ try{ analyse(x,y); System.out.println("so weit ..."); }catch (IllegalArgumentException e) { System.out.println(e.getMessage()); x=0; }finally{ System.out.println("bin am Ende"); } return x*y; } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 93 Beispiel: Ausnahmenbehandlung (2/2) public static void main(String[] args) { Rechner r = new Rechner(); try{ System.out.println("A::"+r.mal(3, 4)); System.out.println("B::"+r.mal(6, 9)); System.out.println("C::"+r.mal(6, 7)); System.out.println("D::"+r.mal(3, 5)); }catch(Nicht42Exception e){ System.out.println(e.getMessage()); }finally{ System.out.println("in main-finally"); } int bumm= 7/0; System.out.println("Ende"); } } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm so weit ... bin am Ende A::12 nicht beantwortbar bin am Ende B::0 bin am Ende nich 42 in main-finally Exception in thread "main" java.lang.Arithmetic Exception: / by zero at Rechner.main(Rechner .java:39) 94 Aufzählungen für Anfänger und Klassiker public class Programmiererfahrung implements Qualifikation{ private String[] stufen={"nicht vorhanden", "Grundkenntnisse","alte Projekterfahrung", "Projektmitarbeiter", "Experte"}; private int stufenwert=0; ... } public class Erfahrung { public final static int NICHT_VORHANDEN=0; public final static int GRUNDKENNTNISSE=1; public final static int ALTE_PROJEKTERFAHRUNG=2; public final static int PROJEKTMITARBEITER=3; public final static int EXPERTE=4; } Zugriff mit: int meineErfahrung= Erfahrung.NICHT_VORHANDEN; Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 95 Aufzählungen mit Enum public enum Erfahrung { NICHT_VORHANDEN, GRUNDKENNTNISSE, ALTE_PROJEKTERFAHRUNG, PROJEKTMITARBEITER, EXPERTE } public class Spielerei { public static void main (String[] s){ Erfahrung ich= Erfahrung.NICHT_VORHANDEN; System.out.println(ich); for(Erfahrung e: Erfahrung.values()) System.out.println(e); NICHT_VORHANDEN } NICHT_VORHANDEN } GRUNDKENNTNISSE ALTE_PROJEKTERFAHRUNG PROJEKTMITARBEITER EXPERTE Benutzeroberflächen und Stephan Kleuker 96 Software-Ergonomie Michaela Ramm Weitere Methoden von enum-“Klassen“ (1/2) Erfahrung ich= Erfahrung.NICHT_VORHANDEN; System.out.println(ich.getClass()); System.out.println(ich.compareTo(Erfahrung.NICHT_VORHANDEN)); System.out.println(ich.compareTo(Erfahrung.EXPERTE)); System.out.println(ich.equals(0)); System.out.println(ich.equals(1)); System.out.println(ich.equals(Erfahrung.NICHT_VORHANDEN)); class Erfahrung 0 -4 false false true Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 97 Weitere Methoden von enum-“Klassen“ (2/2) System.out.println(ich.getDeclaringClass()); System.out.println(ich.name()); System.out.println(ich.ordinal()); System.out.println(Erfahrung.valueOf("EXPERTE")); try{ // try-catch später genauer System.out.println(Erfahrung.valueOf("Experte")); }catch (IllegalArgumentException e){ System.out.println(e); } System.out.println(Erfahrung.valueOf(Erfahrung.class,"EXPERTE")); class Erfahrung NICHT_VORHANDEN 0 EXPERTE java.lang.IllegalArgumentException: Experte EXPERTE Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 98 Objekte von enum-Klassen • Mit enum werden besondere Klassen definiert, sind final (keine Vererbung möglich), keinen von außen nutzbaren Konstruktor • Durch Erfahrung ich= Erfahrung.NICHT_VORHANDEN; erhält man ein Objekt der Klasse Erfahrung • D. h. Enum-Klassen können zusätzlich „normale“ Exemplarmethoden und Exemplarklassen enthalten (auch z. B. toString()) • Klassenmethodenaufruf Erfahrung.klassenmethode(); • Methodenaufruf: ich.exemplarmethode(); Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 99 Erweiterte Möglichkeiten mit enum public enum Coin { PENNY(1), NICKEL(5), DIME(10), QUARTER(25); private final int value; PENNY:1c COPPER Coin(int value) { this.value = value; } public int value() { return value; } NICKEL:5c NICKEL } DIME:10c SILVER QUARTER:25c SILVER public class CoinTest { public static void main(String[] args) { for (Coin c : Coin.values()) System.out.println(c +":"+c.value()+"c "+color(c)); } private enum CoinColor { COPPER, NICKEL, SILVER } private static CoinColor color(Coin c) { switch(c) { case PENNY: return CoinColor.COPPER; case NICKEL: return CoinColor.NICKEL; case DIME: case QUARTER: return CoinColor.SILVER; default: throw new AssertionError("Unknown coin: " + c); } und Stephan Kleuker 100 } Benutzeroberflächen Software-Ergonomie Michaela Ramm } Serialisierung • Zum Speichern und Laden von Objekten stellt Java verschiedene Klassen zur Verfügung • Variante hier: Objektverwandlung in XML • generell: Objekte müssen serialisierbar sein (anschaulich: verwandelbar in String mit Trennzeichen zwischen Werten) • Collection-Klassen und viele weitere der Java-Bibliothek sind serialisierbar (Achtung: im „Zeichenbereich“ viele nicht) import java.io.Serializable; public class Punkt implements Serializable{ private static final long serialVersionUID = 1L; • keine Methode benötigt; Versionsnummer für Änderungen • für XML-Nutzung: get und set für alle Exemplarvariablen und parameterloser Konstruktor Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 101 Beispielausschnitt: Serialisierung (1/4) import java.io.Serializable; import java.util.ArrayList; // ... public class Polygon implements Serializable{ private static final long serialVersionUID = 1L; private boolean geschlossen=false; private List<Punkt> punkte; public Polygon(){punkte=new ArrayList<Punkt>();} public void setGeschlossen(boolean b){geschlossen=b;} public boolean isGeschlossen() {return geschlossen;} //get public List<Punkt> getPunkte() {return punkte;} public void setPunkte(List<Punkt> punkte) { this.punkte = punkte; } public void hinzu(Punkt p){punkte.add(p);} //... Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 102 Beispielausschnitt: Serialisierung (2/4) package main; import java.beans.XMLDecoder; import java.beans.XMLEncoder; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; public class Main { public static void main(String[] args) { Punkt[] ps = { new Punkt(0, 0), new Punkt(3, 3), new Punkt(3, 0) }; Polygon poly = new Polygon(); for (Punkt p : ps) poly.hinzu(p); System.out.println(poly); Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 103 Beispielausschnitt: Serialisierung (3/4) XMLEncoder out = null; try { out = new XMLEncoder(new BufferedOutputStream( new FileOutputStream("Bsp.xml"))); out.writeObject(poly); } catch (FileNotFoundException e) {// wegschauen } finally { out.close(); } poly.setGeschlossen(true); false < (0,0) (3,3) (3,0) > true < (0,0) (3,3) (3,0) > XMLDecoder in = null; false < (0,0) (3,3) (3,0) > Polygon poly2 = null; try { in = new XMLDecoder(new BufferedInputStream( new FileInputStream("Bsp.xml"))); poly2 = ((Polygon) in.readObject()); } catch (FileNotFoundException e) {// wegschauen } finally { in.close(); } System.out.println(poly+"\n"+poly2); } } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 104 Beispielausschnitt: Serialisierung (4/4) „Bsp.xml“ <?xml version="1.0" encoding="UTF-8"?> <java version="1.6.0_12" class="java.beans.XMLDecoder"> <object class="graphik.Polygon"> <void property="punkte"> <void method="add"> <object class="basistypen.Punkt"/> </void> <void method="add"> <object class="basistypen.Punkt"> <void property="x"> <int>3</int> </void> <void property="y"> <int>3</int> </void> </object> </void> <void method="add"> <object class="basistypen.Punkt"> <void property="x"> <int>3</int> </void> </object> und Benutzeroberflächen Stephan Kleuker Software-Ergonomie Michaela Ramm </void> </void> 105 javadoc – Dokumentation (1/3) • • • • • /** Kommentar */ - wird vor Klassen- und Interfacedeklarationen sowie vor Methoden, Konstruktoren und Attributdeklarationen zur Dokumentationsgenerierung berücksichtigt Kommentar wird in HTML-Dokumentation von "javadoc" aufgenommen => HTML-Tags im Kommentar sind erlaubt /** ist Kommentaranfang und */ ist Kommentarende Innerhalb des Kommentars wird ein * am Zeilenanfang ignoriert Erster Satz des Kommentars ist gesonderter Zusammenfassungssatz. (Punkt als Endmarkierung) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 106 javadoc – Dokumentation (2/3) • Durch @-Zeichen innerhalb des Kommentars werden Tags eingefügt, um automatische Querreferenzen zu erzeugen • Bei einigen Tags muss man bei javadoc einstellen, dass sie mit zur Generierung genutzt werden sollen • @see -Tag erzeugt allgemeine Querreferenz – Referenz zu anderer Klasse: @see java.io.InputStream @see String – Referenz zu einer Methode einer Klasse: @see String#equals – Referenz zu anderer HTML-Datei: @see <a href="spec.html">Java Spec</a> • @author -Tag um Autor zu kennzeichnen @author Ego ich @author Ego ich, Me Myself, Io Je Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 107 javadoc – Dokumentation (3/3) • @version -Tag kennzeichnet Version – @version 1.01beta • @param -Tag – Erklärung für Parameter in Methoden und Konstruktorendeklarationen: – @param name der Name des Mitarbeiters • @return -Tag – Bedeutung des Rückgabeparameters • @exception -Tag – Erklärung von Ausnahmen in Methoden und Konstruktordeklarationen: – @exception Nicht42Exception unerwünschter Wert • @deprecated -Tag (ab JDK 1.1) – Kennzeichnung veralteter Methoden Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 108 Anmerkungen • Methoden und Variablen vor der Deklaration kommentieren • Kommentar in Methoden durch Kürze (<15 Zeilen), Struktur (<3 Verzweigungen) und sprechende Namen unnötig • javadoc erstellt HTML-Seiten; Konfigurationsmöglichkeiten für das Aussehen • konfigurierbar, welche Informationen sichtbar sein sollen (z. B. auch private) • javadoc auch zentrale Quelle für Interface-Beschreibung • Variante statt HTML durch Doclets • Alternative auch für Java: Doxygen Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 109 Beispiel - javadoc (1/4) /** Klasse zur Beschreibung eines Punktes in der Ebene. * Koordinaten können nur ganzzahlige Werte annehmen * @author Ego Ich * @version 1.0 */ public class Punkt implements Serializable{ private static final long serialVersionUID = 1L; /** x-Ordinate, Abstand vom Nullpunkt */ private int x; /** y-Ordinate, Abstand zum Nullpunkt */ private int y; /** Methode zur Berechnung des Abstands eines anderen * Punktes. Berechnung nutzt Satz von Pythagoras (oder so) * @param p zweiter Punkt, dessen Abstand zu this bestimmt wird * @return genauer Abstandswert */ public double abstand (Punkt p){ return Math.sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y)); } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 110 Beispiel - javadoc (2/4) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 111 Beispiel - javadoc (3/4) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 112 Beispiel - javadoc (4/4) Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 113 jar-Dateien • Java-Programme (oder Teilprogramme/Komponenten) werden typischerweise als Jar-Dateien ausgeliefert • jar (ist zip-Datei) enthält class-Dateien und weitere genutzte Dateien • jar befindet sich als Programm im bin-Verzeichnis der JavaDistribution • Zur Nutzung einer jar-Datei muss diese in CLASSPATHVariable oder als Parameter beim Programmstart eingetragen werden • eingebundene jar-Dateien können wie andere Klassen auch genutzt werden • typischerweise liegen fremde jar-Dateien in lib-Verzeichnis Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 114 Umgang mit jar (Beispiel) • Einpacken der Informationen im Verzeichnis classes jar cvf blubb.jar paket1 paket2 (alle Dateien in den Verzeichnissen paket1, paket2 und darunter werden eingepackt) C: classes paket1 paket2 • Ergänzung des CLASSPATH mit c:\classes\blubb.jar Klasse1.java Klasse2.java dann an beliebigem Ort ausführbar: java paket1.Klasse1 • oder java –classpath c:\classes\blubb.jar paket1.Klasse1 Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 115 Nutzung externer Bibliothek • Beispiel: Apache Collections http://commons.apache.org/collections/ • herunterladen, zip auspacken, zumindest die Datei commons-collections-3.2.1.jar in sinnvolles Verzeichnis legen • In Projekt einbinden - Achtung, nicht entpacken Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 116 Beispiel - Bag import java.util.Set; import org.apache.commons.collections.Bag; import org.apache.commons.collections.bag.HashBag; public class Main { public static void main(String[] args) { Bag b = new HashBag(); Punkt[] ps = { new Punkt(0,0), new Punkt(3,3), new Punkt(3,0), new Punkt(3,3)}; for(Punkt p:ps) b.add(p); System.out.println(b); b.add(new Punkt(0,0), 3); System.out.println(b); [1:(3,0),1:(0,0),2:(3,3)] System.out.println(ps[0] [1:(3,0),4:(0,0),2:(3,3)] +"::"+b.getCount(ps[0])); (0,0)::4 Set s=b.uniqueSet(); [1:(3,0),1:(0,0),1:(3,3)] Bag b2= new HashBag(s); System.out.println(b2); } Benutzeroberflächen und Stephan Kleuker 117 } Software-Ergonomie Michaela Ramm Software-Design (Modell - View - Controller) • Klassen müssen so strukturiert werden, dass sie wiederverwendbar und weiterentwickelbar sind (-> OOAD) • Basisansatz: Trennung von Ein-/Ausgabe und Berechnung/Datenverwaltung • Datenverwaltung wird auch Model (M) genannt: Beispiele Punkt und Polygon (hat kein System.out, wohl toString()) • Klasse zur Darstellung von Modellinhalten wird View (V) genannt (Ausgabe in Textform oder graphisch oder ...) • Klasse zur Bearbeitung von Modellen wird Controller (C) genannt (z. B. Steuerung durch Nutzer) • Grundidee: Controller bearbeitet Modellinhalte; Modell informiert View über Änderungen (die dann gezeigt werden) • Am Anfang: Zusammenhang zwischen Klassen aufbauen • Varianten: Controller beeinflusst View, ... Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 118 Beispiel: MVC (1/3) public class Model { private View view; private String inhalt=""; public String getInhalt(){ return inhalt; } public void anmelden(View v){ view=v; } public void setInhalt(String inhalt){ if(!this.inhalt.equals(inhalt)){ this.inhalt=inhalt; view.informieren(inhalt); } } Controller +setModel(Model) +aktion() -model 0..1 Model -inhalt: String +getInhalt():String +setInhalt(String) +anmelden(View) -view 0..1 View +informieren(String) } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 119 Beispiel: MVC (2/3) public class View { public void informieren(String i) { System.out.println("neu: "+i); } } public class Controller { private Model model; public void setModel(Model model){ this.model=model; } public void aktion(){ int eingabe=-1; while(eingabe!=0){ System.out.print("Wat nu?\n(0) Ende\n(1) Model ändern: "); eingabe=Eingabe.leseInt(); if(eingabe==1){ System.out.print("Neuer Wert: "); model.setInhalt(Eingabe.leseString()); } } } } Benutzeroberflächen und Stephan Kleuker 120 Software-Ergonomie Michaela Ramm Beispiel: MVC (3/3) public class Main { Wat nu? public static void main(String[] a) { (0) Ende (1) Model ändern: 1 Model m= new Model(); Neuer Wert: Hai Controller c = new Controller(); neu: Hai Wat nu? c.setModel(m); (0) Ende View v = new View(); (1) Model ändern: 1 m.anmelden(v); Neuer Wert: Hai Wat nu? c.aktion(); (0) Ende } (1) Model ändern: 1 } Neuer Wert: Fisch neu: Fisch • Gibt einige Varianten von MVC, Wat nu? z. B. Controller kennt den View (0) Ende (1) Model ändern: 0 • Wichtig ist logische Trennung der Funktionalitäten Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 121 MVC fortgeschritten • zu einem Model kann es mehrere Views geben • Model hat Liste von Views, werden bei Änderungen informiert • um ähnliche Views zu erlauben, realisieren diese ein Interface Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 122 Model-Delegate (MVC-Variante) public class Delegate { private Model model; public void setModel(Model model){ this.model=model; } public void informieren(String i) { System.out.println("neu: "+i); } public void aktion(){ int eingabe=-1; while(eingabe!=0){ System.out.print("Wat nu?\n(0) Ende\n(1) Model ändern: "); eingabe=Eingabe.leseInt(); if(eingabe==1){ System.out.print("Neuer Wert: "); model.setInhalt(Eingabe.leseString()); } } } } Benutzeroberflächen und Software-Ergonomie Stephan Kleuker Michaela Ramm 123