Autoboxing - Nachtrag Universität Paderborn Prof. Dr. Heike Wehrheim „Mit dem Autoboxing ist eine Reihe von Unregelmässigkeiten verbunden, die der Programmierer beachten muss, um Fehler zu vermeiden.“ aus: Christian Ullenboom Java ist auch eine Insel Integertest2.java GP1-WS08/09 484 Beispiel 2 - Hashtabelle Universität Paderborn Prof. Dr. Heike Wehrheim Noten für GP1 in Hashtabelle speichern, ermöglicht schnellen Zugriff per Name des Studenten Was sind die Typen der Einträge? (Name,Note): (String,Double) Also HashMap<String,Double> notengp1 = new HashMap<String,Double>(400); (nicht: HashMap<String,double>, hier wird ein Referenztyp erwartet, dafür Wrapperklasse von double) Dann füllen mit notengp1.put(„Otto“,2.7); notengp1.put(„Edelgart“,1.3); Nachschauen durch notengp1.get(„Otto“); -> 2.7 GP1-WS08/09 485 Universität Paderborn Prof. Dr. Heike Wehrheim Kapitel 2: Grundlagen der Objektorientierung 2.3 Packages, Ein- und Ausgabe, Ausnahmebehandlung GP1-WS08/09 486 Motivation Universität Paderborn Prof. Dr. Heike Wehrheim Bisher: pro Klasse eine Datei, alle stehen in einem Verzeichnis Problem: bei großen Programmen entstehen viele Dateien, nicht mehr klar, welche Klasse wofür zuständig jeder „sieht“ jeden Namenskonflikte: Klassen mit gleichen Namen, aber unterschiedlichen Aufgaben mehr Strukturierung wird benötigt GP1-WS08/09 487 Universität Paderborn Prof. Dr. Heike Wehrheim Pakete - Klassenbibliotheken Thematisch zusammengehörige Klassen- (und Interface-) Deklarationen in Paketen zusammenfassen (engl. packages) Bessere Strukturierung Bessere Kapselung Bessere Wiederverwendung GP1-WS08/09 488 Wie geht das? Universität Paderborn Prof. Dr. Heike Wehrheim Angenommen, wir wollen unsere Circle-Klassen (und Verwandtes) in ein Paket packen für das Paket ein eigenes Unterverzeichnis anlegen: kreise/ alle Dateien der Circle-Klassen (und der von ihnen benutzten Klassen) darunter legen: kreise/Circle2.java , kreise/Punkt.java, … in allen Dateien als erste Anweisung package kreise; schreiben die Klassen in den Dateien, die man von außen benutzen möchte, als public deklarieren; Übersetzen der Klassen aus übergeordnetem Verzeichnis: javac kreise/Punkt.java etc. GP1-WS08/09 489 Benutzung dann … Universität Paderborn Prof. Dr. Heike Wehrheim in Klassen, die kreise-Klassen benutzen möchten und in einer Datei auf dem Verzeichnis darüber liegen, import Befehle am Dateianfang einbauen import kreise.*; // importiert alles in kreise/ import kreise.Circle2; // importiert nur Circle2 GP1-WS08/09 490 Sichtbarkeit in Paketen Universität Paderborn Prof. Dr. Heike Wehrheim Package definiert Gültigkeitsgrenze für Klassennamen, falls nicht als public deklariert public class Sichtbar { ... } außerhalb des Package gültig class Unsichtbar {...} nur innerhalb des Package gültig Erlaubt also eine weitere Art des „Versteckens“ Wenn eine Klasse keine Paket-Definition hat, wird sie standardmäßig im unbenannten Paket (default package) abgelegt (das hatten wir bisher immer) GP1-WS08/09 491 Universität Paderborn Prof. Dr. Heike Wehrheim Sichtbarkeiten 2 Dateien in paket/ package paket; public class Klasse1 { public int x; int y; private int z; public Klasse1() { x=1; y=2; z=3; } } package paket; public class Klasse2 { public static void main (String [] args) { Klasse1 k1 = new Klasse1(); System.out.println(k1.x); System.out.println(k1.y); System.out.println(k1.z); } } Was geht, was nicht? GP1-WS08/09 492 Universität Paderborn Prof. Dr. Heike Wehrheim Sichtbarkeiten II 1 Datei in paket/ package paket; public class Klasse1 { public int x; int y; private int z; public Klasse1() { x=1; y=2; z=3; } } 1 Datei in .. import paket.*; public class Klasse { public static void main (String [] args) { Klasse1 k1 = new Klasse1(); System.out.println(k1.x); System.out.println(k1.y); System.out.println(k1.z); } } Was geht, was nicht? GP1-WS08/09 493 Programmierbibliothek Universität Paderborn Prof. Dr. Heike Wehrheim Java besitzt eine große Programmierbibliothek, die in Paketen organisiert ist Einige Packages, die zu jeder Java-Implementierung gehören: lang Grundlegende Klassen zur Sprache util Nützliche Datenstrukturen mit ihren Operationen io Ein- und Ausgabe awt Graphik und graphische Benutzungsoberflächen event Ereignisbehandlung swing Graphik und graphische Benutzungsoberflächen (GUI), aktuell applet Java Programme im WWW net Operationen in Netzwerken GP1-WS08/09 494 Universität Paderborn Prof. Dr. Heike Wehrheim GP1-WS08/09 495 Benutzung dieser Java-Pakete Universität Paderborn Prof. Dr. Heike Wehrheim Ebenfalls import-Anweisung: import java.util.Date; // nur die Klasse Date import java.util.*; // beliebige Klassen aus java.util Allgemein: import paketpfad.klassenname; oder import paketpfad.*; Kann mehr als ein Paketname sein GP1-WS08/09 496 Hierarchische Strukturierung Universität Paderborn Prof. Dr. Heike Wehrheim Pakete sind oft hierarchisch in Unterpakete gegliedert zeichnen objekte kreise linien rechtecke Pakete: zeichnen liegt in: zeichnen.linien zeichnen.objekte zeichnen.objekte.kreise zeichnen.objekte.rechtecke GP1-WS08/09 zeichnen/ zeichnen/linien zeichnen/objekte zeichnen/objekte/kreise zeichnen/objekte/rechtecke 497 Hierarchische Strukturierung II Universität Paderborn Prof. Dr. Heike Wehrheim zeichnen objekte kreise linien rechtecke Package-Klauseln: z.B. Klassendefinitionen in zeichnen/linien: package zeichnen.linien; Klassendefinitionen in zeichnen/objekte/kreise: package zeichnen.objekte.kreise; Nur eine package Anweisung pro Quelltextdatei GP1-WS08/09 498 Qualifizierte Namen Universität Paderborn Prof. Dr. Heike Wehrheim Import Klausel kann auch weggelassen werden, dann muss der vollständige Name angegeben werden. Beispiel: entweder import zeichnen.objekte.kreise.*; … Circle2 = new Circle2(…); oder kein import und dann zeichnen.objekte.kreise.Circle2 c = new zeichnen.objekte.kreise.Circle2(…); GP1-WS08/09 499 Ein- und Ausgabe Universität Paderborn Prof. Dr. Heike Wehrheim Bisher: Ausgabe auf dem Bildschirm mit System.out.println(…); Einlesen von Parametern, die dem Programm mitgegeben werden, mit z.B. Integer.parseInt(args[0]); … Jetzt: Beliebiges Einlesen von Tastatur aus auch während des Programmlaufs Ein- und Ausgabe in Dateien GP1-WS08/09 500 Klassen dafür Universität Paderborn Prof. Dr. Heike Wehrheim Dafür benutzen wir vordefinierte Klassen: Scanner kann Zeichenketten einlesen und in ihre einzelnen Bestandteile zerlegen File repräsentiert abstrakt Dateien PrintStream, InputStream Klassen für Ein- und Ausgabeströme GP1-WS08/09 501 Universität Paderborn Prof. Dr. Heike Wehrheim Bisher: Ausgabe auf Bildschirm Dafür benutzen wir bereits eine Klasse einer vordefinierten Standardbibliothek, die Ausgabefunktionen verfügbar macht: System class System { ... public static final PrintStream out; public static final InputStream in; } class PrintStream { … void print (String s); void println (String s); void println (); } System.out.print(…) : out Klassenvariable von System, Objekt der Klasse PrintStream mit Methode print GP1-WS08/09 502 System.in Universität Paderborn Prof. Dr. Heike Wehrheim Jetzt: System.in benutzen (Eingabestrom) Beispiel: import java.util.Scanner; Paket mit Scanner importieren class HalloSagen { public static void main (String [] args) { String name; Scanner tastatur=new Scanner(System.in); System.out.print("Wie heisst du? "); name = tastatur.nextLine(); System.out.println("Hallo " + name); } } Eine Zeile lesen HalloSagen.java GP1-WS08/09 503 Scanner Universität Paderborn Prof. Dr. Heike Wehrheim Mögliche Eingabequellen: Tastatur (System.in) Datei (new File(“…“) ) (kommt gleich) String Einige Methoden der Klasse Scanner public String next(); // gibt den nächsten String zurück, nach blank bis blank public double nextDouble(); // gibt die nächste erkannte double Zahl zurück public int nextInt(); // gibt die nächste erkannte int-Zahl zurück public boolean hasNext(); // true, wenn es noch einen nächsten String gibt public boolean hasNextInt() // true, wenn es danach noch ein int gibt GP1-WS08/09 504 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Zeichenkette einlesen und in einzelne Wörter zerlegen import java.util.Scanner; public class Wortanalyse { public static void main (String [] args) { String zeile; Scanner tastatur = new Scanner(System.in); zeile = tastatur.nextLine(); Zweites Scanner s = new Scanner(zeile); Scanner Objekt int i = 1; while (s.hasNext()) { System.out.println("Teil " + i + ": " + s.next()); i++; }}} Wortanalyse.java GP1-WS08/09 505 Weiteres Beispiel Prüfen, ob die richtige Eingabe kommt: import java.util.Scanner; Universität Paderborn Prof. Dr. Heike Wehrheim DatenEinlesen.java public class DatenEinlesen { public static void main (String [] args) { String name; int alter = -1; // -1: Alter undefiniert Scanner eingabe = new Scanner(System.in); System.out.print("Bitte Nachname Vorname Alter: "); name = eingabe.nextLine(); Scanner s = new Scanner(name); String nachname = s.next(); Falls Alter angegeben String vorname = s.next(); ist: einlesen if (s.hasNextInt()) alter = s.nextInt(); System.out.println("Vorname:" + vorname + "\nNachname: "+nachname + "\nAlter: " + alter); }} GP1-WS08/09 506 Einlesen von Datei Universität Paderborn Prof. Dr. Heike Wehrheim Statt vom Terminal nun von Datei einlesen; dazu ein File-Objekt erzeugen, den Scanner aus diesem Objekt lesen lassen Scanner datei = new Scanner(new File(“bla.txt“)); Dateiname Dann: … = datei.nextLine(); GP1-WS08/09 507 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Eine Datei zeilenweise einlesen und die Zeilen in ihre Bestandteile zerlegen Wortanalyse2.java import java.util.Scanner; Für Datei-E/A import java.io.*; public class Wortanalyse2 { public static void main (String [] args) throws IOException { String zeile; Scanner datei = new Scanner(new File("Wortanalyse2.java")); while (datei.hasNextLine()) { zeile = datei.nextLine(); Scanner s = new Scanner(zeile); int i = 1; while (s.hasNext()) { System.out.println("Teil " + i + ": " + s.next()); i++; } System.out.println("========="); }}} GP1-WS08/09 508 Ausgabe in Datei Universität Paderborn Prof. Dr. Heike Wehrheim Ähnlich wie Ausgabe auf Bildschirm. Statt des vordefinierten Ausgabeobjekts System.out werden neue Dateiobjekte (Klasse File) erzeugt und im Konstruktor der PrintStream-Klasse als Ausgabeziel angegeben. Öffnen der Datei: PrintStream ausgabe = new PrintStream(new File(“bla.txt“)); „Drucken“ in Datei: ausgabe.println(“…“); Schliessen der Datei (am Ende): ausgabe.close(); GP1-WS08/09 509 Existiert Datei? Universität Paderborn Prof. Dr. Heike Wehrheim Falls nötig: Prüfen, ob Datei schon existiert File ausgabeDatei = new File(“Bla.txt“); PrintStream ausgabe = null; if ( !ausgabeDatei.exists() ) ausgabe = new PrintStream(ausgabeDatei); else { System.out.println(“Datei existiert schon.“); // sinnvoll fortfahren } GP1-WS08/09 510 Beispiel Universität Paderborn Prof. Dr. Heike Wehrheim Eingabe vom Terminal einlesen und in Datei schreiben, Beenden der Eingabe mit „E“ EingabeInDatei.java import java.util.Scanner; import java.io.*; class EingabeInDatei { public static void main (String [] args) throws IOException { Scanner tastatur = new Scanner(System.in); String zeile; PrintStream ausgabe = new PrintStream (new File("Daten.txt")); do { System.out.print("Ihre naechste Eingabe bitte oder E:"); zeile = tastatur.nextLine(); ausgabe.println(zeile); } while (! zeile.equals("E")); ausgabe.close(); }} GP1-WS08/09 511