Softwaretechnik 1 Vorlesung Neuere Sprachelemente in Java Prof. Dr. Bernhard Rumpe Software Systems Engineering Technische Universität Braunschweig http://www.sse.cs.tu-bs.de/ Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Neuerungen seit Java 5.0 2 vl15.fse/01/K2 Java Spracherweiterungen • Statische Imports • Variable Parameteranzahl • Automatisches Boxing • Annotations • Aufzählungstypen • Iteration • Generische Typen • … Verbesserung der Java Virtual Machine Erweiterung der Klassenbibliothek ... Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Statische Imports 3 vl15.fse/01/K2 alt: Zugriff auf statische Elemente über Klassennamen double s = Math.cos(Math.PI); neu: Import von statischen Elementen, unqualifizierte Verwendung import static java.lang.Math.*; … double s = cos(PI); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Variable Parameteranzahl 4 vl15.fse/01/K2 alt: Methoden nur mit fester Parameteranzahl int sum(int val1, int val2) { ... }; int sum(int val1, int val2, int val3) { ... }; int sum(List values) { ... }; neu: Methoden auch mit beliebiger Parameteranzahl, Zugriff wie auf ein Array int sum(int... values) { int result = 0; for(int i = 0; i < values.length; i++) result += values[i]; return result; } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Automatisches Boxing 5 vl15.fse/01/K2 alt: manuelles „ein- und auspacken“ der primitiven Typen Integer i1 = new Integer (5); list.add(i1); int i2 = i1.intValue() + 2 ; //boxing //unboxing neu: list.add(5); Integer i1 = 5; int i2 = i1 + 2; //auto-boxing //auto-boxing //auto-unboxing Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Annotations 6 vl15.fse/01/K2 Metainformationen im Quellcode Kein direkter Einfluss auf die Semantik Lesbar durch Tools oder Libraries aus Quellcode, Class-Files und zur Laufzeit Eigene Annotations können entwickelt werden Beispiel (JUnit 4 Test): @Test(timeout = 1000) public void testInfinity() { while (true) ; } @ gefolgt vom Annotation-Typ Parameter können übergeben werden Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Aufzählungstypen 7 vl15.fse/01/K2 alt: kein expliziter Aufzählungstyp vorhanden • Abhilfe: • Liste von Konstanten • „Aufzählungsmuster“ neu: enum Wochentag { MO, DI, MI, DO, FR, SA, SO; public boolean isWerktag() { switch(this) { case SO : case SA : return false; default : return true; } } public static void main(String[] args) { Wochentag t = Wochentag.DI; System.out.println(t + " " + t.isWerktag()); } // DI true } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Iteration 8 vl15.fse/01/K2 alt: Schleifensteuerung explizit ausprogrammieren public static void main(String[] args) { for ( int i = 0; i < args.length; i++ ) System.out.println( args[i] ); } neu: „for each“ • verfügbar, falls Interface java.lang.Iterable implementiert wird • für alle neuen Collections und Arrays verfügbar public static void main(String[] args) { for ( String arg : args ) System.out.println( arg ); } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Motivation 9 vl15.fse/01/K2 Bisher: Containerklassen speichern Objekte vom Typ Object ArrayList stringlist = new ArrayList(); stringlist.add (“Hallo“); Folgen: Container akzeptiert jedes Objekt. Kein Schutz gegen Objekte eines „unerwünschten“ Typs. stringlist.add (new Integer(5)); Container liefert immer Object. Cast von Objekten nötig, da Typinformation verloren geht. String s0 = (String) stringlist.get(0); String s1 = (String) stringlist.get(1); // Laufzeitfehler Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Lösung 10 vl15.fse/01/K2 Generische Typen erlauben statische Überprüfung der Typsicherheit zur Übersetzungszeit ArrayList<String> stringlist = new ArrayList <String>(); stringlist.add (“Hallo“); stringlist.add (new Integer(5)); //compile Fehler String s0 = stringlist.get(0); Es werden keine Casts mehr benötigt Typinformation bleibt erhalten Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen 11 vl15.fse/01/K2 Klassen oder Interfaces wie bisher definieren + Typvariable T Typvariable im Klassenrumpf wie konkreter Typ verwendbar class Box <T> { T inhalt; Box (T inhalt) {this.inhalt = inhalt;} void setInhalt (T inhalt) {…}; T getInhalt() {…} ; } Anwendung: Festlegung auf einen konkreten Typ für T Box<String> b1 = new Box<String>(“Hallo“); Box<Integer> b2 = new Box<Integer>(5); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, mehrere Typvariablen 12 vl15.fse/01/K2 Definition mit Typvariablen-Liste: <T1, T2, …> class Pair <T,U> { T first; U second; Anwendung: Pair(T fst, U snd) { first = fst; second = snd; } … } Pair<String, Integer> p = new Pair<String, Integer> (“Hallo“, 5); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Vererbung 13 vl15.fse/01/K2 Von generischen Klassen lassen sich Unterklassen bilden class UniPair <T> extends Pair <T,T> { UniPair(T fst, T snd) { super(fst,snd); } … } Unterklassen müssen keine generischen Klassen sein class StringUniPair extends UniPair <String> { StringUniPair(String fst, String snd) { super(fst,snd); } … } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Vererbung 14 vl15.fse/01/K2 Etwas unintuitive Typbeziehung: LinkedList<String> ist Subtyp von List<String> List<String> ist aber nicht Subtyp von List<Object> List<String> slist = new LinkedList<String>(); List<Object> olist = slist; //nicht möglich olist.add(new Object()); //Zuweisung von Object an String String s = slist.get(0); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Wildcards 15 vl15.fse/01/K2 Problem: Ausgabe einer Collection alt: public void printCollection (Collection c) { Iterator i = c.iterator(); for(k=0; k<c.size(); k++) { System.out.println(i.next()); } } neu: 1. Versuch mit Generics public void printCollection (Collection<Object> c) { for(Object e: c) { System.out.println(e); } } neu: 2. Versuch, Collection<Object> ist kein Supertyp aller Collections, es ist Collection<?> (collection of unknown) public void printCollection (Collection<?> c) { for(Object e: c) { System.out.println(e); } } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Wildcards 16 vl15.fse/01/K2 ArrayList<? extends Number> list; Typargument muss vom Number abgeleitet sein (upper bound wildcard) ArrayList<? super Number> list; Typargument muss Basisklasse vom Number sein (lower bound wildcard) list = new ArrayList<Integer>(); //ok list = new ArrayList<Integer>(); //error list = new ArrayList<Object>(); //error list = new ArrayList<Object>(); //ok Lesen + Number n = list.get(0); Lesen //ok Schreiben list.add(new Integer(5)); //error Number n = list.get(0); //error Schreiben + list.add(new Integer(5)); //ok Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Wildcards 17 vl15.fse/01/K2 Beispiel: List<? extends Number> numberList; List<Integer> intList = new ArrayList<Integer>(); numberList = intList; numberList.add(new Integer(0)); //compile Fehler intList.add(new Integer(0)); Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Typen, Type Bounds 18 vl15.fse/01/K2 Type Bounds mit „extends“ funktionieren nicht nur für Wildcards sondern auch für Typvariablen Einschränkung der Typen durch maximal 1 Oberklasse und beliebige Anzahl von Interfaces class Box<T extends Comparable & Serializable> {…} Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Java 5.0 – Generische Methoden 19 vl15.fse/01/K2 Problem: Elemente eines Arrays in eine Collection füllen 1. Versuch: static void fromArrayToCollection (Object[ ] a, Collection <?> c){ for (Object o : a) c.add(o); // compile Fehler } Objects können nicht in Collection mit unbekanntem Typ eingefügt werden. 2. Versuch: Verwendung einer Generischen Methode, einer Methode, die mit einer Typvariablen parametrisiert ist. static <T> void fromArrayToCollection (T[ ] a, Collection <T> c){ for (T o : a) c.add(o); } Prof. Dr. B. Rumpe Software Systems Engineering TU Braunschweig Seite Neuerungen seit Java 5.0 20 vl15.fse/01/K2 Java Spracherweiterungen • Statische Imports • Variable Parameteranzahl • Automatisches Boxing • Aufzählungstypen • Iteration • Generische Typen • Annotations • … Verbesserung der Java Virtual Machine Erweiterung der Klassenbibliothek ...