Erweiterungen in Java 5 (Java 1.5) Dank an Prof. Dr. Sven Eric Panitz (FH Wiesbaden) Neue Konzepte in Java 5: Erweiterung des Typsystems auf generische Typen verbesserte for-Schleife, Aufzählungstypen, statisches Importieren automatisches Boxen P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 1 Erweiterungen in Java 5 (Java 1.5) Java community process (JPC) Java specification request (JSR) Expertengruppe öffentliche Diskussion Integration in Java P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Methode zur Änderung von Java Spezifikation der Änderung Bei ausreichender Unterstützung von fundierten Verbesserungs- und Erweiterungsvorschläge Wenn keine echten Einwände Seite 2 Generische Typen JSR014 Request zu Generischen Typen Sven Eric Panitz war Mitglied der Expertengruppe Phil Wadler: P raktische Inf ormatik 2, SS Entwurf der Programmiersprache Pizza“ ” als Prototyp zu generischen Typen in Java 2005, F olien Java;5, (12. M ai2005) Seite 3 Generische Klassen Beispiel: Klasse zum Speichern beliebiger Objekte in Java 1.4 class OldBox { Object contents; OldBox(Object contents){this.contents=contents;} } Nachteil: Ziel: P raktische Inf ormatik Object bedeutet: keine Typinformation Elimination möglichst aller Verwendungen von Object Mehr statische Typinformation im Programm 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 4 Beispiel: OldBox Problem: Verlust der statischen Typinformation. Zugriff auf contents erfordert dynamische Typzusicherung mittels cast: class UseOldBox{ public static void main(String [] _){ OldBox b = new OldBox("hello"); String s = (String)b.contents; System.out.println(s.toUpperCase()); System.out.println(((String) s).toUpperCase()); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 5 Beispiel: OldBox Die dynamische Typzusicherung kann bei falscher Verwendung zu einem Laufzeitfehler führen: class UseOldBoxError{ public static void main(String [] _){ OldBox b = new OldBox(new Integer(42)); String s = (String)b.contents; System.out.println(s.toUpperCase()); } } > javac UseOldBoxError.java > java UseOldBoxError Exception in thread "main" java.lang.ClassCastException at UseOldBoxError.main(UseOldBoxError.java:4) P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 6 OldBox mittels generischem Typ in Java 5 class Box<elementType> { elementType contents; Box(elementType contents){this.contents=contents;} } Die Typvariable elementType ist als allquantifiziert zu verstehen. Der Typ der generischen Klasse ist Box<elementType> Konkreter Typ der Objekte kann z.B. Box<String> oder Box<Integer> sein: P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 7 Box-Beispiel class UseBox{ public static void main(String [] _){ Box<String> b1 = new Box<String>("hello"); String s = b1.contents; System.out.println(s.toUpperCase()); System.out.println(b1.contents.toUpperCase()); Box<Integer> b2 = new Box<Integer>(new Integer(42)); System.out.println(b2.contents.intValue()); } } dynamische Typzusicherungen mittels cast fallen weg. b1 hat Typ Box<String> b2 hat Typ Box<Integer> P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 8 Vermeidung dynamischer Typfehler class UseBoxError{ public static void main(String [] _){ Box<String> b = new Box<String>(new Integer(42)); String s = b.contents; System.out.println(s.toUpperCase()); } } statischen Typfehler statt eines Laufzeitfehlers: > javac UseBoxError.java UseBoxError.java:3: cannot find symbol symbol : constructor Box(java.lang.Integer) location: class Box<java.lang.String> Box<String> b = new Box<String>(new Integer(42)); ^ 1 error > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 9 Vererbung Unterklassen von generischen Klassen; Beispiel: class Pair<at,bt> extends Box<at>{ Pair(at x,bt y){ super(x); snd = y; } bt snd; public String toString(){ return "("+contents+","+snd+")"; } } Zum +-Operator: Ist wenigstens einer der beiden Operatoren in a + b ein String, so wird der andere Operator mit toString konvertiert und eine String-Verkettung ausgefhrt. P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 10 Instanzen von generischen Klassen class UsePair{ public static void main(String [] _){ Pair<String,Integer> p = new Pair<String,Integer>("hallo",new Integer(40)); System.out.println(p); System.out.println(p.contents.toUpperCase()); System.out.println(p.snd.intValue()+2); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 11 Beispiel: homogene Paare class UniPair<at> extends Pair<at,at>{ UniPair(at x,at y){super(x,y);} void swap(){ final at z = snd; snd = contents; contents = z; } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 12 Beispiel: HelloWorld mit homogenen Paaren class UseUniPair{ public static void main(String [] _){ UniPair<String> p = new UniPair<String>("welt","hallo"); System.out.println(p); p.swap(); System.out.println(p); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 13 Beispiel: spezifische Unterklasse class StringBox extends Box<String>{ StringBox(String x){super(x);} } class UseStringBox{ public static void main(String [] _){ StringBox b = new StringBox("hallo"); System.out.println(b.contents.length()); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 14 Milnerscher Typcheck in Java Der richtige Typcheck-Algorithmus für Java 5 mit generischen Typen, Klassen und Methoden ist Milners polymorpher Typcheck , (analog zum Typcheck in Haskell) Der Milnersche Typcheck kann nicht umgehen mit: Kombination von Hierarchien und generischen Typen (müsste signifikant erweitert werden) Beschränkung in Java: keine Subtypisierung während des Typchecks P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 15 Einschränken der Typvariablen; Beispiel Beschränkung der Instanziierung auf bestimmte Typen. In Java 1.4 class CollectMaxOld{ private Comparable value; CollectMaxOld(Comparable x) { value=x; } void setValue(Comparable x){ if (value.compareTo(x) < 0) value=x; } Comparable getValue(){return value;} } Objekte der Klasse CollectMaxOld: value ist nicht weiter eingeschränkt nur die Schnittstelle Comparable muss implementiert sein. P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 16 Beispiel mit Untertypen Neu: zusätzliche extends-Klausel für die Typvariablen class CollectMax <elementType extends Comparable> { private elementType value; CollectMax(elementType x) { value=x; } void setValue(elementType x){ if (value.compareTo(x) < 0) value=x; } elementType getValue(){return value;} } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 17 Benutzung der Klasse CollectMax getValue liefert einen konkreten Rückgabetyp class UseCollectMax { public static void main(String [] _){ CollectMax<String> cm = new CollectMax<String>("Brecht"); cm.setValue("Calderon"); cm.setValue("Horvath"); cm.setValue("Shakespeare"); cm.setValue("Schimmelpfennig"); System.out.println(cm.getValue().toUpperCase()); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 18 Generische Schnittstellen Generische Typen auch für Schnittstellen. Funktionalität analog zu generischen Klassen Siehe Beispiel zu equals P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 19 generische Schnittstelle zu equals: Äpfel mit Birnen vergleichen? interface EQ<otherType> { public boolean eq(otherType other); } Nur Äpfel sollen mit Äpfeln verglichen werden können: class Apfel implements EQ<Apfel>{ String sorte; Apfel(String sorte){ this.sorte=sorte;} public boolean eq(Apfel other){ return this.sorte.equals(other.sorte); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 20 generische Schnittstelle Vergleiche Äpfel mit Äpfeln: class TestEq{ public static void main(String [] _){ Apfel a1 = new Apfel("Golden Delicious"); Apfel a2 = new Apfel("Macintosh"); System.out.println(a1.eq(a2)); System.out.println(a1.eq(a1)); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 21 Beispiel: Birnen class Birne implements EQ<Birne>{ String sorte; Birne(String sorte){ this.sorte=sorte;} public boolean eq(Birne other){ return this.sorte.equals(other.sorte); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 22 Beispiel: Birnen = Äpfel Vergleich führt zu einem Typfehler: class TesteEqError{ public static void main(String [] _){ Apfel a = new Apfel("Golden Delicious"); Birne b = new Birne("williams"); System.out.println(a.equals(b)); System.out.println(a.eq(b)); } } > TesteEQError.java:6: eq(Apfel) in Apfel cannot be applied to (Birne) System.out.println(a.eq(b)); ^ 1 error P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 23 Statischer Typcheck verhindert Apfel = Birne class BirneError implements EQ<Apfel>{ String sorte; BirneError(String sorte){ this.sorte=sorte; } public boolean eq(Birne other){ return this.sorte.equals(other.sorte); } } Fehlermeldung: > javac BirneError.java BirneError.java:1: BirneError is not abstract and does not override abstract method eq(Apfel) in EQ class BirneError implements EQ<Apfel>{ ^ P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 24 Generische Untertypen Gegeben Typ A als Untertyp von B, geschrieben A v B. Das kann bewirkt werden durch: • • • A ist eine Unterklasse der Klasse B, oder A implementiert die Schnittstelle B, oder die Schnittstelle A erweitert die Schnittstelle B Frage: Folgt aus A v B auch C < A > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 25 v C < B > (Kovarianz) Beispiel zu generische Untertypen class Kontra{ public static void main(String []_){ Box<Object> b = new Box<String>("hello"); } } Der Javaübersetzer weist dieses Programm zurück: > javac Kontra.java Kontra.java:4: incompatible types found : Box<java.lang.String> required: Box<java.lang.Object> Box<Object> b = new Box<String>("hello"); ^ 1 error > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 26 Generischer Untertyp Box<String> 6v Box<Object> Grund: Nach Zuweisung an eine Variable Box<Object> könnte man sonst über Box<Object> das Attribut contents mit beliebigen Objekten versorgen P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 27 Beispiel für Zuweisungsfehler In Arrays ist der Fehler möglich: class Ko{ public static void main(String []_){ String [] x = {"hello"}; Object [] b = x; b[0] = new Integer(42); x[0].toUpperCase(); } } Laufzeitfehler: > java Ko Exception in thread "main" java.lang.ArrayStoreException at Ko.main(Ko.java:5) > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 28 Generische Sammlungsklassen (Collections) Im Paket java.util von Java 5 sind generische Versionen der Collection-Klassen. import java.util.*; import java.util.List; class ListTest{ public static void main(String [] _){ List<String> xs = new ArrayList<String>(); xs.add("Schimmelpfennig"); xs.add("Shakespeare"); xs.add("Horvath"); xs.add("Brecht"); String x2 = xs.get(1); System.out.println(xs); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 29 Beispiel zu Typen Aus Kompatibilitätsgründen ist auch erlaubt: import java.util.*; import java.util.List; class WarnTest{ public static void main(String [] _){ List xs = new ArrayList<String>(); // <String> fehlt xs.add("Schimmelpfennig"); xs.add("Shakespeare"); xs.add("Horvath"); xs.add("Brecht"); String x2 = (String)xs.get(1); System.out.println(xs); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 30 Beispiel zu Typen (Ausgabe) Warnung: > javac WarnList.java Note: WarnList.java uses unchecked or unsafe operations. Note: Recompile with -warnunchecked for details. > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 31 Generische Methoden Statische Methoden lassen sich generisch definieren. class Trace { static <elementType> elementType trace(elementType x){ System.out.println(x); return x; } public static void main(String [] _){ String x = trace ((trace ("hallo") +trace( " welt")).toUpperCase()); Integer y = trace (new Integer(40+2)); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 32 Iteration Java 1.4 hat kein eigenes Schleifenkonstrukt für einen Iterator In Java 5. gibt es ein Schleifenkonstrukt für Iterator Da es nur endliche Collections gibt, terminiert eine solche Schleife immer. P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 33 Iteration: Beispiel import java.util.List; import java.util.ArrayList; import java.util.Iterator; class OldIteration{ public static void main(String [] _){ String [] ar = {"Brecht","Horvath","Shakespeare","Schimmelpfennig"}; List xs = new ArrayList(); for (int i= 0;i<ar.length;i++){ final String s = ar[i]; xs.add(s); } for (Iterator it=xs.iterator();it.hasNext();){ final String s = (String)it.next(); System.out.println(s.toUpperCase()); } } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 34 Java 5. Iterator-Syntax for (T ype i dentif ier : e xpr){b ody} für jeden i dentif ier des Typs T ype in e xpr führe b ody aus. e xpr muss die Schnittstelle Iterable haben Einzige Methode dazu: iterator() Diese liefert ein Iterator-Objekt (mit Methoden next(), hasNext()) P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 35 Iterations-Beispiel, reformuliert import java.util.List; import java.util.ArrayList; class NewIteration{ public static void main(String [] _){ String [] ar = {"Brecht","Horvath","Shakespeare","Schimmelpfennig"}; List<String> xs = new ArrayList<String>(); for (String s:ar) xs.add(s); for (String s:xs) System.out.println(s.toUpperCase()); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 36 Die neuen Schnittstellen Iterable; Beispiel package util.io; import java.io.Reader; import java.io.BufferedReader; import java.io.IOException; import java.util.Iterator; public class ReaderIterator implements Iterable<Character> ,Iterator<Character>{ private Reader reader; private int n; public ReaderIterator(Reader r){ reader = new BufferedReader(r); try{n = reader.read(); } catch(IOException _){n=-1;} } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 37 Die neuen Schnittstellen Iterable (2) public Character next(){ Character result = new Character((char)n); try{n=reader.read(); } catch(IOException _){n=-1;} return result; } public boolean hasNext(){ return n!=-1; } public void remove(){ throw new UnsupportedOperationException(); } public Iterator<Character> iterator(){return this;} } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 38 Die neuen Schnittstellen Iterable (3) import util.io.ReaderIterator; import java.io.FileReader; class TestReaderIterator { public static void main(String [] args) throws Exception{ Iterable<Character> it = new ReaderIterator(new FileReader(args[0])); for (Character c:it){ System.out.print(c); } } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 39 Die Schnittstellen Iterable (4) Die Methode listToString druckt jedes Objekt aus, das Iterable Methoden implementiert hat, zum Beispiel eine Liste. import java.io.StringWriter; import java.util.Iterator; public class Util { ..... P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 40 Die Schnittstellen Iterable (5) public class Util { public static String listToString(Iterable<?> list, String trennzeichen, String vorne, String hinten) { StringWriter s = new StringWriter(); Iterator<?> it = list.iterator(); s.write(vorne); if (it.hasNext()) { s.write(it.next() + ""); } while (it.hasNext()) { s.write(trennzeichen + " " + it.next()); } s.write(hinten); return s.toString(); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 41 Beispiel zu generischen Sammlungsklassen und for-Schleife Methoden zu String Liste von Wörtern → → Liste von Wörtern, und String import java.util.*; import java.util.List; class TextUtils { static List<String> words (String s){ final List<String> result = new ArrayList<String>(); StringBuffer currentWord = new StringBuffer(); P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 42 Beispiel for (2) for (char c:s.toCharArray()){ if (Character.isWhitespace(c)){ final String newWord = currentWord.toString().trim(); if(newWord.length()>0){ result.add(newWord); currentWord = new StringBuffer(); } } else{currentWord.append(c);} } return result; } static String unwords(List<String> xs){ StringBuffer result = new StringBuffer(); for (String x:xs) result.append(" "+x); return result.toString().trim(); } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 43 Beispiel for (3) public static void main(String []_){ List<String> xs = words(" the world is my Oyster "); for (String x:xs) System.out.println(x); System.out.println(unwords(xs)); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 44 Automatisches Boxen Es gibt zwei Arten von Typen: Objekttypen primitive Typen im Paket java.lang gibt es die Box-Typen: Byte, Short, Integer, Long, Float, Double, Boolean und Character. Damit kann man primitive Daten zu Objekten machen. Objekte dieser Klassen sind nicht modifizierbar. Dies kann in Java 1.4. zu lästigen Vermehrung von Boxing / UnboxingBefehlen führen. Java 5 hat Automatisches Boxing / Unboxing, eingefügt vom Compiler P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 45 Java 1.4-Beispiel Boxing/Unboxing package boxing; public class ManualBoxing{ public static void main(String [] _){ int i1 = 42; Object o = new Integer(i1); System.out.println(o); Integer i2 = new Integer(17); Integer i3 = new Integer(4); int i4 = 21; System.out.println((i2.intValue()+i3.intValue())*i4); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 46 Beispiel Boxing/Unboxing in Java 5 package boxing; public class AutomaticBoxing{ public static void main(String [] _){ int i1 = 42; Object o = i1; System.out.println(o); Integer i2 = 17; Integer i3 = 4; int i4 = 21; System.out.println((i2+i3)*i4); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 47 Boxing / Unboxing-Beispiel In Java 1.4: LinkedList lst = new LinkedList(); lst.add(new Integer(5)); int x = ((Integer) lst.get(0)).intValue(); Java 5: LinkedList<Integer> lst = new lst.add(5); int x = lst.get(0); P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 48 LinkedList<Integer>(); Aufzählungstypen Java 5 hat einen expliziten Aufzählungstyp Beispiel Aufzählungstyp für die Wochentage. package enums; public enum Wochentage { montag,dienstag,mittwoch,donnerstag ,freitag,sonnabend,sonntag; } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 49 Aufzählungstypen Der Compiler erzeugt für die Wochentage die Klassendatei: > javap enums.Wochentage Compiled from "Wochentage.java" public class enums.Wochentage extends java.lang.Enum{ public static final enums.Wochentage montag; public static final enums.Wochentage dienstag; .... public static final enums.Wochentage sonntag; public static final enums.Wochentage[] values(); public static enums.Wochentage valueOf(java.lang.String); public enums.Wochentage(java.lang.String, int); public int compareTo(java.lang.Enum); public int compareTo(java.lang.Object); static {}; } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 50 Verwendung der Aufzählungstypen in switch package enums; public enum Tage { montag,dienstag,mittwoch,donnerstag ,freitag,sonnabend,sonntag; public boolean isWerktag(){ switch (this){ case sonntag : case sonnabend :return false; default :return true; } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 51 Verwendung der Aufzählungstypen in switch (2) public static void main(String [] _){ Tage tag = freitag; System.out.println(tag); System.out.println(tag.ordinal()); System.out.println(tag.isWerktag()); System.out.println(sonntag.isWerktag()); } } > java -classpath classes/enums.Tage freitag 4 true false > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 52 Verwendung der Aufzählungstypen in for package enums; public class IterTage { public static void main(String [] _){ for (Tage tag:Tage.values()) System.out.println(tag.ordinal()+": "+tag); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 53 Verwendung der Aufzählungstypen in for (2) Die erwartete Ausgabe ist: > 0: 1: 2: 3: 4: 5: 6: > java -classpath classes/ montag dienstag mittwoch donnerstag freitag sonnabend sonntag P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) enums.IterTage Seite 54 Beispiel zu Euro-Scheinen package enums; public enum Euroschein { fuenf(5),zehn(10),zwanzig(20),fuenfzig(50),hundert(100), zweihundert(200),tausend(1000); private int value; public Euroschein(int v){value=v;} public int value(){return value();} public static void main(String [] _){ for (Euroschein schein:Euroschein.values()) System.out.println (schein.ordinal()+": "+schein+" -> "+schein.value); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 55 Beispiel zu Euro-Scheinen (2) > 0: 1: 2: 3: 4: 5: 6: > java -classpath classes/enums.Euroschein fuenf -> 5 zehn -> 10 zwanzig -> 20 fuenfzig -> 50 hundert -> 100 zweihundert -> 200 tausend -> 1000 P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 56 Statische Imports in Java 5 Beispiel zum Import von reverse package staticImport; public class StringUtil { static public String reverse(String arg) { StringBuffer result = new StringBuffer(); for (char c:arg.toCharArray()) result.insert(0,c); return result.toString(); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 57 Statische Imports in Java 5 (Folie 2) package staticImport; import static staticImport.StringUtil.*; public class UseStringUtil { static public void main(String [] args) { for (String arg:args) System.out.println(reverse(arg)); } } Die Ausgabe dieses Programms: > java -classpath classes/ ollah tlew > P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) staticImport.UseStringUtil hallo welt Seite 58 Variable Parameteranzahl package java15; public class VarParams{ static public String append(String... args){ String result=""; for (String a:args) result=result+a; return result; } public static void main(String [] _){ System.out.println(append("hello"," ","world")); } } Die Methode append konkatiniert endlich viele String-Objekte. P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 59 Beispiel: was erzeugt der Compiler > javap -classpath classes/ java15.VarParams Compiled from "VarParams.java" public class java15.VarParams extends java.lang.Object{ public java15.VarParams(); public static java.lang.String append(java.lang.String[]); public static void main(java.lang.String[]); } > Konflikt: P raktische Inf ormatik variable Anzahl der Parameter gegen Überladen von Methoden nach Argumentanzahl 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 60 Einige Beispielklassen Einstellige Funktion package crempel.util; public interface UnaryFunction<arg,result>{ public result eval(arg a); } Ebenso können wir eine Schnittstelle für konstante Methoden vorsehen: package crempel.util; public interface Closure<result>{ public result eval(); } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 61 Einige Beispielklassen: Tupelklasse package crempel.util; public class Tuple1<t1> { public t1 e1; public Tuple1(t1 a1){e1=a1;} String parenthes(Object o){return "("+o+")";} String simpleToString(){return e1.toString();} public String toString(){return parenthes(simpleToString());} public boolean equals(Object other){ if (! (other instanceof Tuple1)) return false; return e1.equals(((Tuple1)other).e1); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 62 Einige Beispielklassen: Tupelklasse: 2-Tupel package crempel.util; public class Tuple2<t1,t2> extends Tuple1<t1>{ public t2 e2; public Tuple2(t1 a1,t2 a2){super(a1);e2=a2;} String simpleToString(){ return super.simpleToString()+","+e2.toString();} public boolean equals(Object other){ if (! (other instanceof Tuple2)) return false; return super.equals(other)&& e2.equals(((Tuple2)other).e2); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 63 Einige Beispielklassen: 3-Tupel package crempel.util; public class Tuple3<t1,t2,t3> extends Tuple2<t1,t2>{ public t3 e3; public Tuple3(t1 a1,t2 a2,t3 a3){super(a1,a2);e3=a3;} String simpleToString(){ return super.simpleToString()+","+e3.toString();} public boolean equals(Object other){ if (! (other instanceof Tuple3)) return false; return super.equals(other)&& e3.equals(((Tuple3)other).e3); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 64 Beispiel zu Iteration über Zahlenbereich import java.util.Iterator; public class FromTo implements Iterable<Integer>,Iterator<Integer>{ private final int to; private int from; public FromTo(int f,int t){to=t;from=f;} public boolean hasNext(){return from<=to;} public Integer next(){int result = from;from=from+1;return result;} public Iterator<Integer> iterator(){return this;} public void remove(){new UnsupportedOperationException();} } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 65 Java: Maybe Haskell-Maybe: data Maybe a = Nothing | Just a Java-Maybe: package crempel.util; public interface Maybe<a> {} package crempel.util; public class Nothing<a> implements Maybe<a>{ public String toString(){return "Nothing("+")";} public boolean equals(Object other){ return (other instanceof Nothing); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 66 Java: Maybe (Folie 2) package crempel.util; public class Just<a> implements Maybe<a>{ private a just; public Just(a just){this.just = just;} public a getJust(){return just;} public String toString(){return "Just("+just+")";} public boolean equals(Object other){ if (!(other instanceof Just)) return false; final Just o= (Just) other; return just.equals(o.just); } } P raktische Inf ormatik 2, SS 2005, F olien Java;5, (12. M ai2005) Seite 67