Kapitel 18: Java ein paar Kleinigkeiten zum Schluss Grundlagen der Programmierung 1 Holger Karl Wintersemester 2016/2017 Inhaltsverzeichnis Inhaltsverzeichnis 1 Abbildungsverzeichnis 2 Liste von Definitionen u.ä. 2 18.1 Überblick............................... 3 18.2 Exceptions.............................. 3 18.3 Lambda-Ausdrücke......................... 4 18.4 Generizität.............................. 6 18.5 Pakete................................ 7 18.6 Standardpakete........................... 9 1
18.7 Zusammenfassung......................... 11 Abbildungsverzeichnis 18.1 Beispiel einer UML-Darstellung eines einfachen Paketes mit zwei Klassen............................. 7 18.2 Pakete von Paketen; UML-Darstellung.............. 8 Liste von Definitionen u.ä. 2
18.1. Überblick 3 18.1 Überblick 18.1.1 Was bisher geschah Java Grundlagen Die wundersame Welt der Objektorientierung in Java 18.1.2 Dieses Kapitel Fehlende Kleinigkeiten Betonung einiger Aspekte der aktuellen Java Version 8 18.2 Exceptions 18.2.1 Exceptions Java hat einen Exception-Mechanismus sehr ähnlich zu Python Klassenbasiert; erweiterbar;... Syntax leicht unterschiedlich Behandlung: try und catch (statt except) Auslösen: throw statt raise finally wie final Beispiel 1 try { 2 /* Anweisungen */ 3 } catch (OverflowException UnderflowException e) { 4 /* Anweisungen */ 5 } catch (Exception e) { 6 /* Anweisungen */ 7 } finally { 8 /* Anweisungen */ 9 } 18.2.2 Exceptions im Methodenkopf Besonderheit: Eine Methode kann Exceptions aufzählen, die sie nicht selbst behandelt
4 Liste von Definitionen u.ä. Beispiel: Methode zum Datei öffnen kann ein File not found nicht selbst sinnvoll behandeln Syntax: throws (das s ist wichtig!) als Teil der Signatur 1 class X { 2 void m () throws ExceptionName1, ExcpetionName2, { 3 /* Anweisungen */ 4 if (...) throw ExceptionName1; 5 } 6 } 18.2.3 Nutzung solcher Methoden Angenommen, wir wollen dieses m in einer anderen Methode m1 nutzen Dann müssen alle von m (möglicherweise) geworfenen Exceptions entweder Bei einem Aufruf von m in einem catch behandelt werden oder m1 muss eine nicht behandelte Exception-Klasse ihrerseits im Methodenkopf als throws deklarieren Andernfalls: Compiler stellt fest, dass nicht alle Exceptions behandelt werden Verweigert Übersetzung Konsequenz: spätestens in main wird alles behandelt Ausnahme: System-Exceptions wie NullPointer 18.3 Lambda-Ausdrücke 18.3.1 Java 8: Lambda-Ausdrücke! Vor Java 8: Keine Lambda-Ausdrücke Mit extrem umständlichen Hilfskonstruktionen, z.b. anonyme Klassen, um eine Vergleichsfunktion für Sortieren zu definieren Seit Java 8: Lambda-Ausdrücke; im Prinzip ähnlich zu Python Mit anonymem Interface mit einer Methode Implizit, ohne ausdrückliches Interface 18.3.2 Java 8: Lambda-Ausdrücke Beispiel mit Interface
18.3. Lambda-Ausdrücke 5 1 // wir brauchen zunächst ein Interface als Typ 2 // hier: Integer auf Integer abbilden 3 interface meinfunktionstyp {int exec (int x); } 4 5 // davon können wir eine Variable bauen: 6 meinfunktionstyp f; 7 8 // und an f einen Lambda-Ausdruck zuweisen: 9 f = x -> x * x; 10 11 // Test - Achtung, man muss die Methode aufrufen! 12 int y = f.exec(5); 13 System.out.println(y); f ==> null f ==> $Lambda$6/327177752@56ef9176 y ==> 25 25 18.3.3 Java 8: Lambda-Ausdruck ohne Interface Zwei Lambda-Ausdrücke: Vergleich bei Filter, Ausdrucken Vorsicht, Seiteneffekt! 1 import java.util.stream.stream; 2 3 class Lambda { 4 public static void main (String[] args) { 5 Stream.of(1954, 1974, 1990, 2014).filter(x -> x>1980).foreach(x -> Sys 6 } 7 } -> System.out.println(x)); 1990 2014 Stream Klasse, um funktionale Ansätze auf Folgen von Daten zu unterstützen Wichtige Methoden: filter, foreach, findany, map, of Siehe Referenz
6 Liste von Definitionen u.ä. 18.3.4 Java 8: Lambda vs. Closures Zitat: A closure is a lambda expression paired with an environment that binds each of its free variables to a value. In Java, lambda expressions will be implemented by means of closures, so the two terms have come to be used interchangeably in the community. Aber nur, weil die Java community den Unterschied nicht versteht! 18.4 Generizität 18.4.1 Generizität Bisher: Alle Methoden hatten feste Typen Den gleichen Code immer wieder schreiben, nur weil sich ein Typ ändert? Sortieralgorithmus für Zahlen, einen anderen für Strings,...? Sortieren ist immer gleich nur das Vergleichen und Kopieren unterscheidet sich Optionen: Man fällt auf Object zurück (ggf. durch Boxing) * Nachteil: Wie konvertiert man in eigentlichen Typ zurück? (Z.B. Element aus Liste entnommen?) * Nachteil: In eine Liste für Strings können auch Zahlen abgelegt werden Man erfindet generische Typen 18.4.2 Generische Typen Idee: Man lässt bei einer Klasse einen Typ als Parameter zu! Damit eigentlich eine Familie von Klassen definiert! Beim Instatiieren eines Objekts: Konkreten Typ für den Parameter nennen Beispiel: allgemeine Klasse für Liste, durch Typ parametriert 1 class Liste<T> { 2 T[] data; 3 void add (T x) {... }; 4 T remove() {...}; 5 void sort() {... /* Vergleich von T Objekte */... } 6 } 7
18.5. Pakete 7 8 Liste<String> textliste = new Liste<String>(); 9 textliste.add("hallo"); 10 11 // das gibt Fehler: 12 textliste.add(42); 18.5 Pakete 18.5.1 Pakete Zusammenfassung von Klassen zu größeren Einheiten: Paketen Zuordnung einer Klasse zu Paket Paketname: Anweisung package Paketname; im Kopf der.java-datei der Klasse Beispiel UML Abbildung 18.1: Beispiel einer UML-Darstellung eines einfachen Paketes mit zwei Klassen 18.5.2 Pakete und Verzeichnisse Klassen: Dateien Klasse C in Datei C.java Pakete: Verzeichnisse! Klassen eines Paketes P in Verzeichnis P Beispiel oben: In Verzeichnis graphics die Dateien Circle.java und Rectangle.java 18.5.3 Pakete von Paketen, Verzeichnisse in Verzeichnissen Pakete zu Paketen zusammenfassen Dateien liegen in Unterverzeichnissen von Verzeichnissen 18.5.4 Klassen, Pakete - wo gesucht? Suche beginnt ab aktuellem Verzeichnis
8 Liste von Definitionen u.ä. Abbildung 18.2: Pakete von Paketen; UML-Darstellung Angenommen, static void main ist ein MyApp.java, was Teil des Pakets graphics ist, was Teil des Pakets utilities ist Dann Übersetzen (javac) bzw. Starten (java) Ab Verzeichnis oberhalb von Utilities javac utilities/graphics/myapp.java java utilities/graphics/myapp Zustätzliche Suche ab Verzeichnissen in Umgebungsvariable CLASSPATH Eine häufige Fehlerquelle! 18.5.5 Explizites Importieren aus Paketen Tpyischerweise: Klassen aus Paketen importieren Anweisung: import Direkt nach Anweisung package Folge der Paketnamen und Klassenname! Durch Punkt getrennt Fügt Klasse dem Namensraum hinzu Beispiel: import utilities.graphics.circles Dann: Circle c = new Circle() 18.5.6 Implizites Importieren Klassen auch nutzbar durch Angabe des vollständig qualifizierten Paketnamens Ohne import Beispiel: utilities.graphics.circle c = new utilities.graphics.circle() 18.5.7 Sichtbarkeit bzgl. Paketen Java ist ja bei der Sichtbarkeit von Methoden einer Klasse schon paranoid Das ist bei Sichtbarkeit von Klassen in Paketen nicht anders Klassen können mit public etc. versehen werden Default: Package private Zugriff nur von innerhalb des Pakets Siehe auch Stack Overflow Diskussion Wir präzisieren obige Tabelle:
18.6. Standardpakete 9 Die beiden Spalten Paket und Unterklasse (gleiches Paket) sind natpürlich gleich; das soll nur Unterschied zu Unterklasse in anderem Paket verdeutlichen Annotation Klasse selbst Paket Unterklasse (gleiches Paket) Unterklasse (anderes Paket) public Ja Ja Ja Ja Ja protectedja Ja Ja Ja Nein keine Angabe Ja Ja Ja Nein Nein private Ja Nein Nein Nein Nein Andere Klasse/von aussen Anmerkung: keine Angabe entspricht einer Art package Das gibt es aber nicht als Schlüsselwort 18.6 Standardpakete 18.6.1 Standardpakete java.lang: Standardklassen wie String java.io: Klassen für Ein-/Ausgabe in Dateien, Tastatur,... java.util: Hilfsklasse wie Random, Date,... sowie die das Collection Paket (siehe unten) javax.swing: Paket für graphische Benutzeroberfläche 18.6.2 Standardpakete: java.util.collection Wichtiges Paket für Standard-Datentypen: Listen, Mengen, Dictionaries,... Als generische Typen Samt Iteratoren Details z.b. Kapitel 23, Mössenböck Kern: Interface Collection Von den meisten Klassen dieses Pakets implementiert 18.6.3 Standardpakete: java.util.collection Interface Collection Typische Methoden für alle Collections:
10 Liste von Definitionen u.ä. add remove clear contains size 18.6.4 Standardpakete: java.util.collection Interface Iterator Iterator bietet Methoden: hasnext next remove (aus Sammlung entfernen) Generisch, passend zum Typ der in Collection gespeichert ist 18.6.5 Standardpakete: java.util.collection Beispiel ArrayList 1 ArrayList<String> liste = new ArrayList<String>(); 2 3 liste.add("hallo"); 4 liste.add("gp1"); 5 6 // Mit for iterieren: 7 for (String s: liste) System.out.println(s); 8 9 // Mit einem expliziten Itertor iterieren: 10 Iterator<String> it = liste.iterator(); 11 while (it.hasnext()) System.out.println(it.next()); liste ==> [] $2 ==> true $3 ==> true Hallo GP1 it ==> java.util.arraylist$itr@56ef9176 Hallo GP1 18.6.6 Standardpakete: java.util.collection Beispiel FileInputStream Datenstrom: Abstraktion einer (potentiell unendlichen) Folge von Daten Ein- oder Ausgabe Unterschiedlich granular: Bytes,... Unterschiedliche Ziele: Dateien,...
18.7. Zusammenfassung 11 Beispiel: Datei zeichenweise kopieren 1 import java.io.*; 2 3 class CharacterwiseCopying { 4 public static void main (String[] args) throws IOException { 5 Reader r = new FileReader(args[0]); 6 Writer w = new FileWriter(args[1]); 7 int ch = r.read(); 8 while (ch >= 0) { w.write(ch); ch = re.read(); } 9 r.close(); 10 w.closer(); 11 } 12 } 18.7 Zusammenfassung 18.7.1 Zusammenfassung Mit Java 8 versucht die Sprache, Anschluss an sinnvolle Konzepte zu halten Für praktische Programmierung wichtige Konzepte vorhanden Generizität Eine sinnvolle Sammlung von Standardpaketen Insgesamt: Java zahlt einen hohen Preis für die statische Typisierung!