1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 14. Dateien • Datei (engl. file): Folge von „Datensätzen“ (i. Allg.) im dauerhaften (persistenten) Sekundärspeicher • am Ende erweiterbar • (meist) Datensätze zusammengefasst in gleichgroßen Seiten (z.B. 4 KB) • beim Zugriff auf Sekundärspeicher wird eine vollständige Seite übertragen → Pufferung • logische Dateien auch zur Kommunikation zwischen Prozessen (→ Pipes, VS) 129 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Formen von Dateien • sequentielle Datei: Datensätze der Reihe nach bearbeitet • Datei mit wahlfreien Zugriff (random access file): • auf beliebigen Datensatz direkt zugreifbar (vgl. Array) • hierauf aufbauend: B-Bäume, (dynamische) Hashverfahren, . . . • nicht bei Magnetbändern, Pipes,. . . , aber bei Platten, CDs, DVDs. . . 130 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 14.1 Dateien in Java • in Java: komplizierte Klassenhierarchie unterschiedlicher Dateiformen • auf Bytes bzw. Zeichen • zum Lesen bzw. Schreiben • gepuffert bzw. ungepuffert • hier nur Ausschnitt (Klassen sind jeweils Unterklassen von Object) 131 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Klassenhierarchie für Dateien • InputStream (abstrakt) → Byte-Datei lesen • ByteArrayInputStream • FileInputStream • FilterInputStream (mit 4 Unterklassen) • ObjectInputStream implements ObjectInput • PipedInputStream • SequenceInputStream • RandomAccessFile implements DataInput, DataOutput 132 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Klassenhierarchie für Dateien (2) • OutputStream (abstrakt) → Byte-Datei schreiben • ByteArrayOutputStream • FileOutputStream • ObjectOutputStream • FilterOutputStream (mit 3 Unterklassen) • PipedOutputStream • Reader (abstrakt, 6 Unterklassen) • Writer (abstrakt, 7 Unterklassen) → Zeichen-Datei lesen → Zeichen-Datei schreiben • ... 133 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 14.2 Sequentielle Dateien in Java public class ObjectInputStream extends InputStream implements ObjectInput, ObjectStreamConstants{ public ObjectImportStream(InputStream in) // Konstruktor throws IOExeption, StreamCorruptedException; public int available() throws IOException; public void close() throws IOException; public int read() throws IOException; public int read(byte[] data, int offset, int length) ... public boolean readBoolean() throws IOException; public byte readByte() throws IOException; public char readChar() throws IOException; 134 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Sequentielle Dateien in Java (2) public double readDouble() throws IOException; public float readFloat() throws IOException; public int readInt() throws IOException; public long readLong() throws IOException; public short readShort() throws IOException; public final Object readObject() throws IOException, OptionalDataException, ClassNotFoundException; protected final boolean enableResolveObject(boolean enable) throws SecurityException; protected Object resolveObject(Object o) throws IOException ...} 135 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Sequentielle Dateien in Java (3) public class ObjectOutputStream extends OutputStream implements ObjectOutput{ public ObjectOutputStream(OutputStream o) throws IOException; public void flush() throws IOException; public void write(int data) throws IOException; public void write(byte[]b) throws IOException; public void write(byte[]b, int off, int len) throws IOException; public void writeBoolean(boolean b) throws IOException; public void writeByte(int data) throws IOException; public void writeBytes(String data) throws IOException; 136 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Sequentielle Dateien in Java (4) public void writeChar(int data) throws IOException; public void writeChars(String data) throws IOException; public void writeDouble(double data) throws IOException; public void writeFloat(flout data) throws IOException; public void writeInt(int data) throws IOException; public void writeLong(long data) throws IOException; public void writeShort(short data) throws IOException; public void writeObject( Object obj) throws IOException; ...} 137 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Verwendung von ObjectOutputStream import java.io.*; public class Test1{ public static void main(String argv[]){ try{ FileOutputStream fos = new FileOutputStream("test.data"); ObjectOutputStream out = new ObjectOutputStream(fos); for(int i=1; i<1000; i++){ out.writeInt(i); out.writeDouble(1.0/(double) i);} out.flush(); out.close();} catch (Exception e){ e.printStackTrace();}} } 138 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Verwendung von ObjectInputStream import java. io.*; public class Test2{ public static void main(String argv[]){ int i; double sum=0.0; try{ FileInputStream fis = new FileInputStream("test.data"); ObjectInputStream in = new ObjectInputStream(fis); while (true){ i = in.readInt(); sum += in.readDouble();}} catch (EOFException a){ System.out.println("H("+i+"):"+ sum);} catch (Exception e){e.printStackTrace();}} } bei Binär- und Text-Dateien (z.B. mit Editor erstellt) direkt von fis lesen z.B. char c = (char) fis.read(); 139 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 14.3 Serialisierung • die Klassen ObjectInputStream und ObjectOutputStream ermöglichen nicht nur das Lesen bzw. Schreiben von Basiswerten sondern auch von Objekten • ein Objekt enthält/referenziert oft andere Objekte ( → Objektgraph, ggfs. zyklisch) → I/O eines Objekts erfordert rekursiven I/O des gesamten zugehörigen Objektgraphen • zur Speicherung in einer Datei wird ein Objektgraph von Java automatisch in eine Byte- bzw. Zeichenfolge transformiert • beachte: das Einlesen eines serialisierten Objektgraphen kann in einem „veränderten Umfeld“ (andere Rechner, andere Klassen) erfolgen → bei Serialisierung: Meta-Informationen (über Klassen,. . . ) mitangelegt 140 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Serialisierung (2) • die Serialisierung in Java ist äußerst komfortabel (im Vergleich zu anderen Sprachen, wo nur I/O von Basiswerten möglich!) • Objekte sind nur serialisierbar, wenn die zugehörige Klasse das Interface Serializable implementiert • durch Überschreiben der Methoden readObject und writeObject lässt sich der Serialisierungsmechanismus an spezielle Benutzerbedürfnisse anpassen 141 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Serialisierung (3) Klassendiagramm möglicher Objektgraph Department: Department name 1 * Employee Vector/List: Element: Marketing Element: null name addEmployee,... Employee: Kötter Employee: Kämper bei Serialisierung: • Objektreferenzen werden ersetzt durch Positionsangaben der referenzierten Objekte in der erzeugten Byte- bzw. Zeichenfolge • jedes Objekt wird nur einmal abgelegt (auch bei Zyklen und Mehrfachreferenzen) 142 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Datei Department.java package serialexample; // im gleichnamigen Verzeichnis import java.io.*; import java.util.*; public class Department implements Serializable{ protected String name; protected Vector<Employee> employees = new Vector<Employee>(); public Department(String name){ this.name = name;} public void addEmployee(Employee e){ employees.addElement(e);} public Employee getEmployee(int index){ return employees.elementAt(index);} public String getName(){return name;} } 143 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Datei Employee.java package serialexample; import java.io.*; public class Employee implements Serializable{ protected String name; protected Department dep; public Employee(String n, Department d){ name = n; dep = d; dep.addEmployee(this);} public String getName(){return name;} } 144 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Datei Test.java package serialexample; import java.io.*; public class Test{ public static void main(String argv[]) throws Exception{ Department dep = new Department("Marketing"); new Employee("Kämper", dep); new Employee("Kötter", dep); FileOutputStream fos = new FileOutputStream("test.dat"); ObjectOutputStream out = new ObjectOutputStream(fos); out.writeObject(dep); out.flush(); out.close(); FileInputStream fis = new FileInputStream("test.dat"); ObjectInputStream in = new ObjectInputStream(fis); Department dep2 = (Department) in.readObject(); in.close(); System.out.println(dep2.getName()+":" + dep2.getEmployee(0).getName()+"," + dep2.getEmployee(1).getName();} } 145 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 14.4 Dateien mit wahlfreiem Zugriff in Java pubic class RandomAccessFile implements DataInput, DataOutput{ public RandomAccessFile(String filename, String mode) throws IOException // modes: "r" (lesen) oder "rw" (lesen und schreiben) public RandomAccessFile(File file, String mode) ... public native long getFilePointer() throws IOException; public native void seek(long pos) throws IOException; public int read() throws IOException; public int read(byte[] buffer) throws IOException; public int read(byte[] buffer, int off, int count) ... public final boolean readBoolean() throws IOException; analog: readByte,readChar,readDouble,readFloat,readInt,... 146 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Dateien mit wahlfreiem Zugriff in Java (2) public void write(int b) throws IOException; public void write(byte[] buffer) throws IOException; public void write(byte[] buffer, int off, int count) ... public final void writeBoolean(boolean b) ... analog: writeByte, writeChar,... public native long length() throws IOException; public native void close() throws IOException; } 147 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Wahlfreier Zugriff import java.io.*; class Test{ public static void main(String[] args){ try { RandomAccessFile raf = new RandomAccessFile(args[0],"rw"); long start = raf.getFilePointer(); for (int i=0; i<1000; i++) raf.writeInt(i); raf.seek((long) start + 100); System.out.println(raf.readInt()); // → 25 raf.seek((long) start + 3000); System.out.println(raf.readInt()); // → 750 raf.close();} catch (IOException e){System.out.println(e);}} } Verwendung: javac Test.java; java Test test.dat 148 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 15. Wert- vs. Referenzsemantik Wertsemantik • bei einer Zuweisung bzw. Parameterübergabe wird der Wert kopiert • beide Kopien werden unabhängig voneinander verwendet • Vergleich w1 == w2 liefert true, gdw. w1 und w2 den gleichen Wert haben (ggf. aber unterschiedliche Speicherplätze) • in Java verwendet bei Basiswerten (int, float, . . . ), z.B. int i = 1; int k = 1; int j = i; j++; System.out.println(i+j); → 3 System.out.println(i==k); → true 149 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Referenzsemantik • bei einer Zuweisung bzw. Parameterübergabe wird die Referenz kopiert (nicht der Wert) • beide Referenzen verweisen anschließend auf den gleichen Speicherbereich • Änderungen beeinflussen das (eine!) durch beide Referenzen bezeichnete Objekt • in Java verwendet bei Arrays und Objekten • Vergleich o1 == o2 liefert true, gdw. o1 und o2 das identische Objekt referenzieren • Wertsemantik-Vergleich von Objekten/Arrays möglich durch: geeignetes Überschreiben der Methode equals (aus Klasse Object) • default von equals: Referenzsemantik 150 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Wert- und Referenzsemantik class Punkt{ protected int x, y; public Punkt(int x0, int y0){x=x0; y=y0;} public void verschiebe(int dx, int dy){x+=dx; y+=dy;} public boolean equals(Punkt p){return x==p.x && y==p.y;} public Punkt copy(){return new Punkt(x,y);} } ... Punkt p1 = new Punkt(1,2); Punkt p2 = p1.copy(); Punkt p3 = p1; System.out.println(p1 == p2); → false System.out.println(p1.equals(p2)); → true p3.verschiebe(3,4); System.out.println(p1.equals(p2)); → false 151 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 16. Java-Speicherverwaltung • der Speicherplatz für nicht mehr erreichbare Objekte wird vom Laufzeitsystem automatisch freigegeben und anderweitig wiederverwendet (garbage collection) → enorme Programmiererleichterung gegenüber anderen Sprachen (z.B. C, Pascal) → (geringer) Laufzeitoverhead Beispiel: Punkt p = new Punkt(2,5); p = new Punkt(1,3); • das mit new Punkt(2,5) erzeugte Objekt ist nicht mehr erreichbar • der zugehörige Speicherplatz wird bei Bedarf freigegeben 152 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Speicherverwaltung (Fortsetzung) • durch Beseitigung aller Referenzen: → gezielte Freigabe eines Objekts, z.B. p = null; (“leere Referenz”) • vor der Freigabe wird, falls vorhanden, die finalize-Methode des Objekts ausgeführt • hierdurch können ggfs. weitere Ressourcen wie Dateien freigegeben werden Beispiel: public void finalize(){ ... vom Objekt verwendete Datei schließen ...} 153 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 17. Applets • Applets sind spezielle Java-Klassen, die von einem Webbrowser (clientseitig) ausgeführt werden • sie werden über Applet-Tags in HTML-Seiten eingebunden • eingeschränkte Rechte (keine Dateizugriffe, eingeschränkte Kommunikation) → Sandbox • statt einer main-Methode: Methoden init, start, stop, destroy bei Bedarf überschreiben 154 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Applets (2) init(): initialisiert Applet (vgl. Konstruktor) stop(): wird ausgeführt, wenn Browser Appletseite verlässt ggf. Ressourcen freigeben, Animation anhalten,. . . start(): ausgeführt, wenn Browser Appletseite erneut anzeigt ggf. Ressourcen wieder bereitstellen, Animation reaktivieren,. . . destroy(): ausgeführt, wenn Applet zerstört wird ggf. Ressourcen freigeben 155 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Applet “Zähler” HTML-Seite mit Applet-Tag: <html> <head><title>Zaehler-Applet</title></head> <body> <H2><font color=cyan>Test-Applet</font></H2><br> <applet code="Zaehler.class" width=300 height=120> Ihr Browser unterst&uuml;tzt Java leider nicht! </applet> </body> </html> 156 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Applet “Zähler” (2) import java.applet.*; import java.awt.*; import java.lang.*; import java.awt.event.*; public class Zaehler extends Applet implements ActionListener{ protected TextField zstand = new TextField("0",4); protected Button weiter = new Button("Weiterzaehlen"); protected Button zurueck = new Button("Zuruecksetzen"); public void init(){System.out.println("Applet initialisiert"); setBackground(Color.white); add(new Label("Zaehlerstand: ")); add(zstand); add(weiter); add(zurueck); weiter.addActionListener(this); zurueck.addActionListener(this);} 157 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Applet “Zähler” (3) public void start(){System.out.println("Applet gestartet");} public void stop(){System.out.println("Applet gestoppt");} public void destroy(){System.out.println("Applet entfernt");} public void actionPerformed(ActionEvent event){ if (event.getSource() == weiter) zstand.setText(""+(1+ Integer.parseInt(zstand.getText()))); else if (event.getSource() == zurueck) zstand.setText("0");} } 158 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Kritzel-Applet import java.applet.*; import java.awt.*; import java.awt.event.*; public class Scribble1 extends Applet{ protected int x, y; protected Graphics g; private class MyMouseListener extends MouseMotionAdapter{ public void mouseMoved(MouseEvent e){ x = e.getX(); y = e.getY();} public void mouseDragged(MouseEvent e){ int newx = e.getX(); int newy = e.getY(); g.drawLine(x,y,newx,newy); x = newx; y = newy;}} public void init(){ g = getGraphics(); getAudioClip(getCodeBase(),"gong.au").play(); addMouseMotionListener(new MyMouseListener());} } 159 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 18. Nebenläufigkeit • mehrere Anweisungsfolgen (Threads) lassen sich nebenläufig ausführen • (u.a.) damit logisch unabhängige Programmteile nicht unnötig sequentialisiert werden und sich ggf. gegenseitig blockieren • z.B. beim Überwachen von Sensoren oder Kommunikationsverbindungen • auf einem Prozessor: Threads verzahnt ausgeführt, z.B. Thread1 Thread2 Thread3 Thread1 Thread3 Thread2 ... Zeit 160 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Thread in Java • muss Interface Runnable implementieren (insbesondere Methode run()) oder Klasse Thread erweitern (und run() überschreiben) • Thread t wird gestartet durch t.start() • dies bewirkt Aufruf der Methode run() des Thread-Objekts • weitere Features: (→ Literatur) setPriority(p), ThreadLocal, volatile, holdsLock, join, TimerTask, ThreadGroup 161 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Kritzel-Applet mit Farbwechsel public class Scribble extends Applet{ protected int x, y; protected Graphics g; protected Thread th; private class MyMouseListener extends MouseMotionAdapter{ ... wie vorher ...} private class ColorChanger extends Thread{ public void run(){ try{while (true){ setBackground(Color.white); sleep(10000); // in msec setBackground(Color.yellow); sleep(10000);}} catch(InterruptedException e){System.out.println("beendet");}}} public void init(){ g = getGraphics(); addMouseMotionListener(new MyMouseListener()); th = new ColorChanger(); th.start();} public void stop(){th = null;} } 162 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Kommunikation • Threads können über gemeinsam benutzte Objekte/Variablen kommunizieren • Problem: durch Threadwechsel ggf. ungewollte Effekte Beispielszenario: verzahnte Überweisungen (vgl. SimpelBank) konto2.saldo Thread 80 Thread1 : konto2.getSaldo() → 80 80 Thread2 : konto2.getSaldo() → 80 90 Thread2 : konto2.setSaldo(80+10) 90 (statt 100) Thread1 : konto2.setSaldo(80+10) 163 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Synchronisation durch Java-Monitore • ungewollte Threadverzahnung muss verhindert werden! • hierzu: Methoden als synchronized kennzeichnen • zu jedem Zeitpunkt kann nur ≤ ein Thread synchronized-Methoden jedes Objekts ausführen • ein weiterer Thread, der eine synchronized-Methode des Objekts aufrufen will, wartet (→ Warteschlange), bis die synchronized-Methoden von anderen Threads verlassen wurden Beispiel: public static synchronized void ueberweise(Konto ziel, int betrag){ saldo = saldo - betrag; ziel.setSaldo(ziel.getSaldo()+betrag);} 164 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Synchronisation von Anweisungsfolgen • auch Anweisungsfolgen lassen sich als synchronized kennzeichnen • z.B.: synchronized(this){ ziel.setSaldo(ziel.getSaldo()+betrag);} • allgemein: synchronized(hSperrobjekti){hAnweisungi∗ } 165 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP wait() und notify() Szenario: • während der Ausführung einer synchronized-Methode m muss gewartet werden, bis eine Bedingung (abh. von Attributen) erfüllt ist • wenn m die Exklusivrechte nicht aufgibt: Stillstand! Abhilfe: • durch wait(); kann der Thread angehalten werden • ein anderer Thread kann dann weiterarbeiten (und die Attribute ändern) (auch durch eine synchronized-Methode) • durch notify() kann ein angehaltener Thread reaktiviert werden • alternativ: notifyAll() reaktiviert alle hierauf wartenden Threads • wait() und notity() nur in synchronized-Methoden verwendbar 166 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Dinierende Philosophen public class Dining{ private static final int n = 5; // #Philosophen protected Staebchen stab[] = new Staebchen[n]; private class Staebchen{... s.u....} private class Philosoph implements Runnable{ private int nr; public Philosoph(int i){nr = i;} public void essen(){stab[nr].nehmen(); stab[(nr+n-1)%n].nehmen(); System.out.println("Philosoph "+nr+" isst");} // ggf. Deadlock! public void denken(){stab[nr].ablegen(); stab[(nr+n-1)%n].ablegen(); System.out.println("Philosoph "+nr+" denkt");} public void run(){while(true){essen(); denken();}}} public Dining(){ for(int i=0; i<n; i++) stab[i] = new Staebchen(); for(int i=0; i<n; i++) new Thread(new Philosoph(i)).start();} public static void main(String[] args){new Dining();} } 167 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Dinierende Philosophen: Klasse Stäbchen private class Staebchen{ private boolean verfuegbar = true; public synchronized void nehmen(){ try{while (!verfuegbar) wait(); verfuegbar=false;} catch(Exception e){System.out.println("Abbruch");}} public synchronized void ablegen(){ verfuegbar = true; notify();} } 168 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 19. Generelle Programmierprinzipien 19.1 Lesbarkeit verbessern • aussagekräftige Namen schlecht: hilf, merker, speicher, feld, messreihe, x besser: DurchschnittsUmsatz, ProfilTiefe • Konstanten benennen (→ auch leichter änderbar) static final int GrundPraemie = 150; static final int Zulage = 20; Praemie = Grundpraemie + Zulage * DienstJahre; statt p = 150 + 20*d 169 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Lesbarkeit verbessern (2) • bei kurzen Bezeichner (wie x) Verwechslungsgefahr durch Tippfehler • wenig aussagekräftige Kommentare weglassen, z.B. i = i+1; // i inkrementieren • Zusammengehörigkeit durch das Layout hervorheben (→ Einrücktiefe) 170 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 19.2 Problemadäquate Datentypen • möglichst direkte Umsetzung der Datenstrukturen der Anwendung in Programmiersprache, hierzu: • geeignete Basistypen, z.B. int stunde; statt float stunde; • Aufzählungstypen (enum), Unterbereichstypen statt int • Typen so wählen, dass unzulässige Werte zu Typfehlern führen 171 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Unterbereichstypen • bieten Teilmengen der Werte eines anderen Typs • Beispiel: 0..23 statt int • in Java im Gegensatz zu anderen Sprachen (Pascal,Ada,. . . ): keine syntaktische Unterstützung von Unterbereichstypen • in Java simulierbar 172 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Simulation von Unterbereichstyp public final class Stunde{ private int st; public class StundeException extends Exception{} public Stunde(int s) throws StundeException{ if ((s<0) || (s>23)) throw new StundeException(); st = s;} public void next(){st = (st+1) % 24;} public String toString(){return ""+st;} } • Anwendung: z.B. Stunde st = new Stunde(23); st.next(); System.out.println(st); 173 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 19.3 Schrittweise Verfeinerung • zur Strukturierung grobe Version mit abstrakten Daten und abstrakten Befehlen ausgehend von Spezifikation einer Systemkomponente schrittweise verfeinern • Schritte der groben Versionen bleiben als Kommentare in detaillierter Version • hierfür günstig: Hypertext-Editor (z.B. Visual Studio.NET) • Einrücktiefe dokumentiert Verfeinerungsniveau • Reihenfolge der Verfeinerung kann günstig gewählt werden z.B. Kern vor Initialisierung, Schleifen und Verzweigungen früh • kein Geheimnisprinzip 174 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP Beispiel: Schrittweise Verfeinerung //********************************************* // Sortieren eines Arrays durch direkte Auswahl //********************************************* public static void selSort(int[] a){ // bis Restarray einelementig // Minimum in Restarray suchen // Minimum mit erstem Element vertauschen } 175 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 1. Verfeinerung public static void selSort(int[] a){ // bis Restarray einelementig for(int i = 0; i <= a.length-2; i++) // Minimum in Restarray suchen // Index des Minimums initialisieren // fuer jedes Element des Restarrays // Element bei Min-Bildung beachten // Minimum mit erstem Element vertauschen } 176 1.Bsp Typen Feld Kontr. OO GUI IK Exc. Gen. Loop Box Enum Junit Datei Wert GC Applet Thread GP 2. Verfeinerung public static void selSort(int[] a){ // bis Restarray einelementig for(int i = 0; i <= a.length-2; i++){ // Minimum in Restarray suchen // Index des Minimums initialisieren int minidx = i; // fuer jedes Element des Restarrays for (int j = i+1; j <= a.length-1; j++){ // Element bei Min-Bildung beachten if (a[j] < a[minidx]) minidx = j;} // Minimum mit erstem Element vertauschen int hilf = a[i]; a[i] = a[minidx]; a[minidx] = hilf;} } 177