Start von Java

Werbung
Start von Java-Programmen
Grundlagen Programmierung
Stephan Kleuker
558
Bisher
• In BlueJ wurde Objekt erzeugt und dann Methode
ausgewählt
• alternativ könnte man jetzt direkt auf Klasse eine noch zu
schreibende Klassenmethode ausführen
• Ansatz weiter gedacht: Klasse heißt ausführbar, wenn sie
eine Methode mit folgender Signatur hat
public static void main(String[] arg){…
Grundlagen Programmierung
Stephan Kleuker
559
Nutzung einer Main-Klasse
• sinnvoll ist es, eigene Klasse Main zu ergänzen, die
ausschließlich zum Start des Programmes genutzt wird
• Erstellung notwendiger Objekte und Aufruf von Methoden,
damit Objekte "sich kennen"
• Start einer Hauptmethode
public class Main{
public static void main(String[] arg){
Studentenverwaltung s = new Studentenverwaltung();
s.steuern();
}
}
Grundlagen Programmierung
Stephan Kleuker
560
Aufruf von main in BlueJ
• Klassenmethode
auswählen
• Array kann direkt
eingegeben werden
(meist ohne Bedeutung,
dann leer lassen)
Grundlagen Programmierung
Stephan Kleuker
561
Vom Source Code zum ausführbaren Programm
Java Source
(Punkt.java)
Java Bytecode
(Punkt.class)
Java Compiler
(javac)
Just-in-time
Compiler
Java Virtual
Machine (java))
• Source Code wird vom Compiler in Bytecode übersetzt
• Bytecode wird von JVM ausgeführt (d.h. interpretiert)
• Ggf. werden über den JIT-Compiler bestimmte
Befehlssequenzen in nativen Code übersetzt
Grundlagen Programmierung
Stephan Kleuker
562
Kompilierung mit der Konsole - Ausgangssituation
Grundlagen Programmierung
Stephan Kleuker
563
Kompilierung mit der Konsole - Kompilieren
Grundlagen Programmierung
Stephan Kleuker
564
Kompilierung mit der Konsole - Ausführen
man erkennt,
dass die Shell
kein UTF-8
"spricht"
Grundlagen Programmierung
Stephan Kleuker
565
ausführbares Programm in BlueJ (1/4)
• Annahme: gibt
Klasse Main mit
main-Methode
• Packen des
Programms in eine
jar-Datei
(vergleichbar einer
zip-Datei mit einem
bestimmten Aufbau)
Grundlagen Programmierung
Stephan Kleuker
566
ausführbares Programm in BlueJ (2/4)
• Auswahl der Startklasse (könnte mehrere main geben)
Grundlagen Programmierung
Stephan Kleuker
567
ausführbares Programm in BlueJ (3/4)
• Speichern der jar-Datei
• jar-Datei unter jedem Betriebssystem nutzbar
Grundlagen Programmierung
Stephan Kleuker
568
ausführbares Programm in BlueJ (4/4)
• Kommando-Zeile (oder Batch-Datei)
• wenn graphisch (AWT oder Swing) und im Betriebssystem
konfiguriert, dann Start durch Doppelklick
Grundlagen Programmierung
Stephan Kleuker
569
Nutzung von Übergabeparametern (1/2)
public class MainAnalyse{
public static void main(String[] s){
if(s==null){
System.out.println("null");
} else {
if(s.length==0){
System.out.println("kein Parameter");
} else {
for(Integer i=0; i<s.length; i =i+1){
System.out.println(i+": "+s[i]);
}
}
}
}
}Grundlagen Programmierung
Stephan Kleuker
570
Nutzung von Übergabeparametern (2/2)
Grundlagen Programmierung
Stephan Kleuker
571
Entwicklungsumgebungen
Grundlagen Programmierung
Stephan Kleuker
572
Programmentwicklung in Java
• Grundsätzlich reicht ein beliebiger Texteditor zur
Programmerstellung, der Inhalt unformatiert speichert
• Klasse K muss in Datei K.java stehen
• java und javac benötigt
• Problem: viele projekteinheitlich zu lösende Aufgaben
müssen individuell geregelt werden
– welche Einrückungen
– woher kommen benötigte Klassen anderer
– wer kompiliert Gesamtprojekt
– wer erstellt wie die Dokumentation
– ………
Grundlagen Programmierung
Stephan Kleuker
573
Entwicklungsumgebung BlueJ
BlueJ übernimmt einige typische Aufgaben:
• Code-Formatierung (Einrückungen)
• Syntax-Highlighting von Schlüsselwörtern
• Einfaches Manövrieren in Klassen
• Unmittelbare Möglichkeit zur Ausführung
• Testklassendefinition und Testausführung (JUnit)
• Einfach Debug-Möglichkeiten
• aber, Entwicklungsumgebungen für Profis können
wesentlich mehr
• aber, nur BlueJ kann direkt mit Objekten kommunizieren
• Fazit: BlueJ sehr gut zum Lernen geeignet, da man
gezwungen wird, alles selbst zu tippen; für größere Projekte
eher ungeeignet
Grundlagen Programmierung
Stephan Kleuker
574
Entwicklungsumgebung Eclipse
•
•
•
•
•
•
•
•
•
•
•
•
Editor mit Syntax-Highlighting und Formatierung
Anzeige aller Fehler
einfaches Starten von Programmen
einfaches Einbinden anderer Programme und Bibliotheken
einfaches Ausführen von JUnit-Tests
viele Möglichkeiten zur Code-Generierung: get-, set- Methoden,
Varianten von Konstruktoren, equals, hashCode, toString
Einbau umgebender try-catch-Blöcke
mächtige Code-Completion (<Strg>+<Space>)
einfache Nutzung eines sehr mächtigen Debuggers
schnelles Manövrieren zu nutzenden und genutzten Methoden
………
Achtung: man benötigt zunächst nur sehr wenige der vielen
Möglichkeiten, Schritt für Schritt vortasten
Grundlagen Programmierung
Stephan Kleuker
575
Beispiel: Studierendenverwaltung (1/4) - Eingabe
Grundlagen Programmierung
Stephan Kleuker
576
Beispiel: Studierendenverwaltung (2/4) - Ausführen
Grundlagen Programmierung
Stephan Kleuker
577
Beispiel: Studierendenverwaltung (3/4) - Debugging
Grundlagen Programmierung
Stephan Kleuker
578
Beispiel: Studierendenverwaltung (4/4) - Testen
Grundlagen Programmierung
Stephan Kleuker
579
Erweiterbarkeit von Eclipse
• Eclipse kann einfach durch Plug Ins erweitert werden
• viele verschiedene Programmiersprachen und Werkzeuge z.
B. zur Datenbankverwaltung möglich
• Vorwegwarnung: Jedes Plug In macht Eclipse langsamer
• Einige weitere Unterstützung bei der Programmierung
• statische Quellcode-Analyse
– detaillierte Prüfungen von Style-Guides (Einrückungen
bis magic Numbers)
– Bewertung der Komplexität von Programmen (Anzahl
der Verzeigungen)
• Messung von Testüberdeckungen (wird Anweisung oder
Zweig geprüft)
• ………
Grundlagen Programmierung
Stephan Kleuker
580
Beispiel: Eclemma für Testüberdeckung
Grundlagen Programmierung
Stephan Kleuker
581
Eclipse als IDE
• IDE = Integrated Development Environment
• Gesamter Entwicklungsprozess umfasst Phasen
– Anforderungsanalyse
– Design
– Programmierung
– Test
• eine IDE unterstützt mehrere dieser Phasen
• eine IDE unterstützt die Verwaltung der Ergebnisse
(Versionsmanagement)
• eine IDE unterstützt den Zusammenbau und die Installation
der Software (Build-Management)
• trotzdem bleibt IDE nur ein [zentraler] Teil der Entwicklung
Grundlagen Programmierung
Stephan Kleuker
582
Pakete
Grundlagen Programmierung
Stephan Kleuker
583
Idee von Paketen
• Große Mengen von Klassen oft sehr unübersichtlich
• Ähnlich zu Dateisystemen ist eine logische Ordnung in
verschiedenen Ordnern sinnvoll
• Ordner werden in Java Paket (package genannt)
• Paketzugehörigkeitsdeklaration steht immer am Anfang der
Klasse
package de.ossoft.gui;
public class Maske{
• Datei Maske.java muss im Unterordner de/ossoft/gui des
Projekts liegen
• Nutzung von Klassen aus anderen Paketen über import
import de.ossoft.gui.Maske;
Grundlagen Programmierung
Stephan Kleuker
584
Ausschnitt: Java-Pakete der Klassenbibliothek
java.util
Contains the collections framework, legacy collection classes,
event model, date and time facilities, internationalization, and
miscellaneous utility classes (a string tokenizer, a randomnumber generator, and a bit array).
java.util.
concurrent
Utility classes commonly useful in concurrent programming.
java.util.
A small toolkit of classes that support lock-free thread-safe
concurrent.atomic programming on single variables.
java.util.
concurrent.locks
java.util.jar
java.util.logging
Interfaces and classes providing a framework for locking and
waiting for conditions that is distinct from built-in
synchronization and monitors.
Provides classes for reading and writing the JAR (Java ARchive)
file format, which is based on the standard ZIP file format with
an optional manifest file.
Provides the classes and interfaces of the JavaTM 2 platform's
core logging facilities.
Grundlagen Programmierung
Stephan Kleuker
585
Pakete in BlueJ
• etwas aufwändig über das Menü
Grundlagen Programmierung
Stephan Kleuker
586
Klassen in Pakete verschieben (1/2)
• leider funktioniert hier kein Drag & Drop in BlueJ
Grundlagen Programmierung
Stephan Kleuker
587
Klassen in Pakete verschieben (2/5)
• Trick: Paketdeklaration direkt in Klasse eintragen
Grundlagen Programmierung
Stephan Kleuker
588
Klassen in Pakete verschieben (3/5)
• Frage bei "Compile" bestätigen mit "Move" bestätigen
Grundlagen Programmierung
Stephan Kleuker
589
Klassen in Pakete verschieben (4/5)
• Generell müssen Pakete erst angelegt werden, sonst
Grundlagen Programmierung
Stephan Kleuker
590
Klassen in Pakete verschieben (5/5)
• Später Paket (Ordner) mit Doppelklick öffnen
Grundlagen Programmierung
Stephan Kleuker
591
Beispiel: einfache Software-Architektur (1/3)
• bisher bei Studentenverwaltung alle
Klassen in einem (dem default-) Paket
eine typische Aufteilung:
• entity-Paket: alle zu verwaltenden
Datenklassen (typisch fast nur get- und
set- Methoden)
• control-Paket: Verwaltungsklassen, die
Sammlungen von Entity-Objekten
verwalten; Zugriff auf Entity-Objekte
nur über Control-Klassen
• boundary-Paket: externer Zugriff auf
Verwaltungsklassen, z. B.
Nutzungsoberfläche
Grundlagen Programmierung
Stephan Kleuker
592
Beispiel: einfache Software-Architektur (2/3)
entity
control (Zugriff auf entity-Objekte)
Grundlagen Programmierung
Stephan Kleuker
593
Beispiel: einfache Software-Architektur (3/3)
• boundary (Zugriff auf control-Objekte)
• fehlt: Aufteilung von Boundary und Control
Grundlagen Programmierung
Stephan Kleuker
594
Pakete und Imports
package boundary;
import control.Studentenverwaltung;
public class Studentendialog {
private Studentenverwaltung verwaltung
= new Studentenverwaltung();
package control;
import entity.Student;
import entity.Austauschstudent;
// weitere Imports
public class Studentenverwaltung {
private ArrayList<Student> studenten;
private String semester = "Semester XXXX";
Grundlagen Programmierung
Stephan Kleuker
595
Aufteilung in Boundary und Control-Funktionalität (1/2)
//alt in Studentenverwaltung
public void anzahlAustauschstudentenAusgeben() {
EinUndAusgabe io = new EinUndAusgabe();
io.ausgeben("Es gibt "
+ anzahlAustauschstudenten()
+ " Austauschstudenten\n");
}
public Integer anzahlAustauschstudenten() {
Integer ergebnis = 0;
for (Student s : this.studenten) {
ergebnis = ergebnis + s.zaehlenAlsAustauschstudent();
}
return ergebnis;
}
Grundlagen Programmierung
Stephan Kleuker
596
Aufteilung in Boundary und Control-Funktionalität (2/2)
// neu: boundary (StudentenDialog)
public void anzahlAustauschstudentenAusgeben() {
EinUndAusgabe io = new EinUndAusgabe();
io.ausgeben("Es gibt "
+ verwaltung.anzahlAustauschstudenten()
+ " Austauschstudenten\n");
}
// neu: control (Studentenverwaltung)
public Integer anzahlAustauschstudenten() {
Integer ergebnis = 0;
for (Student s : this.studenten) {
ergebnis = ergebnis + s.zaehlenAlsAustauschstudent();
}
return ergebnis;
}
Grundlagen Programmierung
Stephan Kleuker
597
Aufteilung in Boundary und Control-Funktionalität (1/4)
//alt in Studentenverwaltung
public void studentSuchen() {
EinUndAusgabe io = new EinUndAusgabe();
Integer mat = zahlZwischen("Matrikelnummer"
, 99999, 1000000);
Student s = studentSuchen(mat);
if (s != null) {
io.ausgeben("Daten: " + s + "\n");
} else {
io.ausgeben("nicht gefunden\n");
}
}
Grundlagen Programmierung
Stephan Kleuker
598
Aufteilung in Boundary und Control-Funktionalität (2/4)
//alt in Studentenverwaltung
public Student studentSuchen(Integer mat) {
Student ergebnis = null;
for (Student s : this.studenten) {
if (s.getMatrikelnummer().equals(mat)) {
ergebnis = s;
}
}
return ergebnis;
}
Grundlagen Programmierung
Stephan Kleuker
599
Aufteilung in Boundary und Control-Funktionalität (3/4)
// neu: boundary (StudentenDialog)
public void studentSuchen() {
EinUndAusgabe io = new EinUndAusgabe();
Integer mat = zahlZwischen("Matrikelnummer"
, 99999, 1000000);
String s = verwaltung.studentAusgeben(mat);
if (s != null) {
io.ausgeben("Daten: " + s + "\n");
} else {
io.ausgeben("nicht gefunden\n");
}
}
Grundlagen Programmierung
Stephan Kleuker
600
Aufteilung in Boundary und Control-Funktionalität (4/4)
// neu: control (Studentenverwaltung)
private Student studentSuchen(Integer mat) {
Student ergebnis = null;
for (Student s : this.studenten) {
if (s.getMatrikelnummer().equals(mat)) {
ergebnis = s;
}
}
return ergebnis;
}
public String studentAusgeben(Integer mat){
Student s=studentSuchen(mat);
if(s==null){
return null;
}
return s.toString();
} Programmierung
Grundlagen
Stephan Kleuker
601
alle Studieren in Control-Klasse
public ArrayList<String> studentenAusgeben() {
ArrayList<String> ergebnis = new ArrayList<String>();
for (Student s : this.studenten) {
ergebnis.add(s.toString());
}
return ergebnis;
}
• Beispiel zeigt deutlich, dass Boundary-Klassen keinen
direkten Zugriff auf Entity-Klassen erhalten
• (Anmerkung: Ansatz wird nicht immer so konsequent
eingehalten)
• Ansatz erlaubt leichte Erstellung einer grafischen Oberfläche
Grundlagen Programmierung
Stephan Kleuker
602
Ergänztes Main-Paket
package main;
import boundary.Studentendialog;
public class Main{
public static void main(
String[] arg){
Studentendialog s =
new Studentendialog();
s.steuern();
}
}
Grundlagen Programmierung
Stephan Kleuker
603
Kompilieren und Ausführen in der Konsole
Grundlagen Programmierung
Stephan Kleuker
604
Beispiel: Pakete und Compilieren
\home\blubb\a
package a;
import a.d.D;
import a.b.c.C;
public class A{
dies ist File
\home\blubb\a\A.java
\home\blubb\a\d
\home\blubb\a\b
package a.d;
import a.b.B;
public class D{
private B b=null;
}
package a.b;
public class B {…}
class Ghost {…}
\home\blubb\a\b\c
package a.b.c;
import a.d.D;
public class C {}
Grundlagen Programmierung
Compiliert wird im Verzeichnis
oberhalb von a (also in blubb) mit
javac a\A.java
Ausführung (auch in blubb)
java a.A
Stephan Kleuker
605
Nutzung von CLASSPATH
• Damit Java Verzeichnisse mit Paketen findet, sollte die
Umgebungsvariable CLASSPATH gesetzt werden
• Diese Variable enthält die Start-Verzeichnisse, in denen bei
einem Aufruf nach Klassen oder Paketen gesucht wird
• Beim Aufruf >java C durchsucht das Laufzeitsystem
sämtliche in CLASSPATH angegebenen Verzeichnisse nach
C.class und führt diese aus
• Beim Aufruf >java a.b.c.C sucht das Laufzeitsystem
C.class in den Unterverzeichnissen a\b\c von
Verzeichnissen aus CLASSPATH
• Voreingestellt ist meist CLASSPATH=. (oder nichts), in
Eclipse zusätzlich das Projektverzeichnis
Grundlagen Programmierung
Stephan Kleuker
606
Beispiel: Paketnutzung (1/2)
package verwaltung.resourcen;
import
import
import
import
import
java.text.DateFormat;
java.text.ParseException;
java.text.SimpleDateFormat;
java.util.Date;
java.util.Locale;
public class Person {
private Date geburt;
private String name;
private Locale loc;
public Person(String geburt, String name)
throws ParseException{
DateFormat df = new SimpleDateFormat("dd.MM.yyyy");
this.geburt = df.parse(geburt);
this.name = name;
}
Benutzeroberflächen und
Software-Ergonomie
Stephan Kleuker
607
Beispiel: Paketnutzung (2/2)
public Person(String name){
this.geburt = new Date();
this.name=name;
}
public void setLoc(Locale loc){ this.loc=loc;}
@Override public String toString(){
return name+": "+DateFormat.getDateInstance(
DateFormat.LONG, loc).format(geburt);
}
}
public static void main(String[] s) throws ParseException{
Person[] pers={new Person("31.2.2000","Ute"),
new Person("Mischa")};
Locale[] loc={Locale.GERMAN, Locale.US, Locale.ITALIAN};
for(Person p:pers){
Ute: 2. März 2000
for(Locale l:loc){
Ute: March 2, 2000
p.setLoc(l);
Ute: 2 marzo 2000
System.out.println(p);
Mischa: 6. Februar 2012
}
}
Mischa: February 6, 2012
Benutzeroberflächen und
Stephan Kleuker
608
} Software-Ergonomie
Mischa: 6 febbraio 2012
Einige Realitätsbeichten
Grundlagen Programmierung
Stephan Kleuker
609
Bisher
• Konsequente Orientierung an Objektorientierung
• folgende Vokabeln auf alle objektorientierten Sprachen
übertragbar: Klasse, Objekt, Objektvariable,
Objektmethode, Sichtbarkeit, abstrakte Klasse,
Klassenvariable, Klassenmethode, Paket
• konsequente Orientierung an Klassen, deshalb Nutzung von
Integer, Double, Boolean
• Integer x=42; x ist echtes Objekt mit Methoden
• Objekte der oben genannten Klassen (auch String) sind
Konstanten, d. h. es können mit Methoden ihre Inhalte nicht
verändert werden (gibt keine set-Methoden)
Grundlagen Programmierung
Stephan Kleuker
610
Java ist nicht konsequent objektorientiert
• gleiches gilt für C++ und C#
Hintergrund
• C++ zunächst nur als Erweiterung von C konzipiert
• Kompromiss, es sollten alle C-Programme weiter laufen
• Resultat, C hatte einfache Datentypen, die keine Klassen sind
und diese wurden nach C++ übernommen
• Resultat, die durchgehende sehr saubere Idee der
Objektorientierung wird mit Füßen getreten, es entsteht ein
Mixed-Stil
• Java sollte auch für C++-Entwickler schnell nutzbar sein,
deshalb einfache, nicht objektorientierte Typen übernommen
Hinweis: gibt echte objektorientierte Sprachen: Smalltalk (seit
1970er), Ruby
Grundlagen Programmierung
Stephan Kleuker
611
primitive Datentypen
Typ
repräsentiert
boolean
true or false
char
Unicode-Zeichen
byte
ganze Zahl mit Vorzeichen
Größe
1 bit
16 bits
8 bits
short
- ´´ -
16 bits
int
- ´´ -
32 bits
long
- ´´ -
64 bits
float
IEEE 754-Fließkommazahl
double
void
Prof. Dr. Stephan Kleuker
32 bits
- ´´ -
64 bits
-
Stephan Kleuker
612
Beispielnutzung
public class Analyse{
}
public static void schleife(){
double[] arr = {0.2, 3., 7e300, 42.42};
for(int i=0; i<4; i=i+1){
System.out.println(i+" :"+ (arr[i]*i));
}
0 :0.0
}
1 :3.0
2 :1.4E301
3 :127.26
Grundlagen Programmierung
Stephan Kleuker
613
Einfache Typen vor Java 5
• einfache Typen nicht in Sammlungen nutzbar
• vor Java 5: Werte von Hand umwandeln (casten)
public static void sammlung(){
ArrayList<Integer> al = new ArrayList<Integer>();
int x = 42;
Integer xo = new Integer(x);
al.add(xo);
int y = (int)al.get(0);
42
System.out.println(y);
}
Grundlagen Programmierung
Stephan Kleuker
614
Ab Java 5: Autoboxing
• Kompiler wandelt bei Bedarf von int nach Integer und
Integer nach int um
• eher workaround, nicht wirklich sauber und auch langsam
Integer x = 42;
int y = x;
Integer z = y;
• einfache Typen können keine null-Werte annehmen
• fieser Laufzeitfehler:
Integer n = null;
int m = n;
Grundlagen Programmierung
Stephan Kleuker
615
Beispiel: Autoboxing
public static void boxen(){
ArrayList<Integer> al = new ArrayList<Integer>();
Integer x = new Integer(99999);
al.add(42); // int nach Integer
al.add(42+1);
al.add(x);
al.add(x+1); // Integer nach int, int nach Integer
al.add(al.get(3)-1);
for(int i:al){
System.out.print(i+" ");
}
boolean identisch = (al.get(2)==al.get(4));
System.out.println("\n identisch: "+ identisch);
System.out.println(" gleich: "+ al.get(2).equals(al.get(4)));
}
42 43 99999 100000 99999
identisch: false
gleich: true
Grundlagen Programmierung
Stephan Kleuker
616
Zahlenbereiche und Genauigkeiten: int
• einfache Datentypen und zugehörige Klassen können nur
endlich viele Werte annehmen
public static void intgenau(){
Integer max = Integer.MAX_VALUE;
for(int i=0; i<3; i=i+1){
System.out.println(max+i);
}
Integer min = Integer.MIN_VALUE;
for(int i=0; i<3; i=i+1){
System.out.println(min-i);
}
}
Grundlagen Programmierung
Stephan Kleuker
2147483647
-2147483648
-2147483647
-2147483648
2147483647
2147483646
617
Zahlenbereiche und Genauigkeiten: double (1/3)
• sehr großer Zahlenbereich, Zahlen wie 1E12 ist 1*1012
• nicht jede Zahl darstellbar
• bekannte besondere Werte Infinity, -Infinity, NaN
public static void doubleGenau(){
Double max = Double.MAX_VALUE;
for(double i=250; i<=300; i=i+10){
System.out.print(Math.pow(10,i)+" ");
System.out.println(max+Math.pow(10,i));
}
}
1.0E250 1.7976931348623157E308
9.999999999999999E259 1.7976931348623157E308
1.0E270 1.7976931348623157E308
1.0E280 1.7976931348623157E308
1.0E290 1.7976931348623157E308
1.0E300 Infinity
Grundlagen Programmierung
Stephan Kleuker
618
Zahlenbereiche und Genauigkeiten: double (2/3)
public static void doublegenau2(){
Double winz = Double.MIN_NORMAL;
System.out.println(winz);
for(double i=10; i<=16; i=i+1){
System.out.println(Math.pow(10,-i)+": "+winz*Math.pow(10,-i));
}
System.out.println(winz/0);
System.out.println(0./0); 2.2250738585072014E-308
}
1.0E-10: 2.225074E-318
1.0000000000000001E-11: 2.22507E-319
1.0E-12: 2.2253E-320
1.0E-13: 2.223E-321
1.0E-14: 2.2E-322
1.0E-15: 2.5E-323
1.0E-16: 0.0
Infinity
NaN
Grundlagen Programmierung
Stephan Kleuker
619
Zahlenbereiche und Genauigkeiten: double (3/3)
public static void verschwindendeMillionen(){
Double konto = 0.0;
Double abziehen = 1E6;
konto = konto + 1E20 -abziehen - 1E20;
System.out.println(konto);
konto = 0.0;
konto = konto + 1E21 -abziehen - 1E21;
System.out.println(konto);
konto = 0.0;
konto = konto + 1E22 -abziehen - 1E22;
System.out.println(konto);
}
-999424.0
-1048576.0
0.0
Grundlagen Programmierung
Stephan Kleuker
620
Bearbeitung von Geldsummen
• Beispiele zeigen: kein Double für Geldsummen
• Beispiele zeigen: Integer (Long) eventuell zu klein
• Ansatz: Schreibe eigene Klasse Geld
• naiv: basierend auf Strings: "1234" + "567" = "1801"
• alternativ ArrayList<Integer> mit den einzelnen Ziffern der
Zahlen
• Java bietet Klassen BigInteger und BigDecimal an
• natürlich sehr viel langsamer als einfache Typen
Grundlagen Programmierung
Stephan Kleuker
621
Beispielnutzung von BigInteger
import java.math.BigInteger;
// …
public static void big(){
BigInteger b = new BigInteger("12345");
for(int i=0; i<4; i=i+1){
b = b.multiply(b);
System.out.println(b);
}
}
152399025
23225462820950625
539422123247359763587428687890625
290976227048689786699404610508159269970874403200651318511962890625
Grundlagen Programmierung
Stephan Kleuker
622
Inkrement- und Dekrementoperatoren
Operator
Bedeutung
x++
ergibt x und erhöht x um 1
++x
ergibt x+1 und erhöht x um 1
x--
ergibt x und verringert x um 1
--x
ergibt x-1 und verringert x um 1
Prof. Dr. Stephan Kleuker
Stephan Kleuker
623
Beispiele für Operatorennutzung
public class IncTest {
public static void main(String args[]){
int i = 1;
System.out.println(“i: “+ i);
i: 1
System.out.println(“++i: “+ ++i);
++i:
System.out.println(“i++: “+ i++);
i++:
System.out.println(“i: “+ i);
i: 3
System.out.println(“--i: “+ --i);
--i:
System.out.println(“i--: “+ i--);
i--:
System.out.println(“i: “+ i);
i: 1
}
2
2
2
2
}
Prof. Dr. Stephan Kleuker
Stephan Kleuker
624
Typkonvertierungen (elementare Typen)
Generell: Variablen von Typ x dürfen nur Elemente dieses Typs
zugewiesen werden
Bei Datentypen findet automatisch eine Konvertierung in
größeren Typen statt (niemals automatisch in Gegenrichtung)
byte short int long float double
char
• Umwandlung in die andere Richtung mit Casten (Typ in
Klammern)
int x=
double
double
// int
int z3
4;
y= 2;
z1= x/y;
z2= x/y; gibt Fehler
= (int) (x/y);
Prof. Dr. Stephan Kleuker
Stephan Kleuker
625
Logische Operatoren
Operator
Bedeutung
&
Und mit vollständiger Auswertung
|
Oder mit vollständiger Auswertung
^
wahr, wenn Operanden unterschiedlich sind
!
Negation
&&
Und mit Kurzschlussauswertung
||
Oder mit Kurzschlussauswertung
Prof. Dr. Stephan Kleuker
Stephan Kleuker
626
Beispielauswertung logischer Operatoren (1/2)
public static boolean effekt(String s){
System.out.println("Aha "+s);
return true;
}
public static void seiteneffekt(){
boolean wahr = true;
boolean falsch = false;
if(wahr || effekt("A")){
}
if(wahr | effekt("B")){
}
if(false && effekt("C")){
}
if(false & effekt("D")){
}
}
Grundlagen Programmierung
Stephan Kleuker
Aha B
Aha D
627
Beispielauswertung logischer Operatoren (2/2)
public static void seiteneffekt2(){
if(effekt("E") ^ effekt("F")){
System.out.println("Hoho");
}
if(effekt("G") ^ !effekt("H")){
System.out.println("Haha");
}
if(!effekt("I") ^ effekt("J")){
System.out.println("Huhu");
}
if(!effekt("K") ^ !effekt("L")){
System.out.println("Hihi");
}
}
Grundlagen Programmierung
Stephan Kleuker
Aha E
Aha F
Aha G
Aha H
Haha
Aha I
Aha J
Huhu
Aha K
Aha L
628
Code-Formatierungen
• bisherige Code-Formatierungen können so beibehalten
werden, da sie Lesbarkeit garantieren
• Möglichkeit: Weglassen von this und super
• Möglichkeit: Weglassen geschweifter Klammern, wenn nur
ein Befehl folgt
• Möglichkeit: Direkter Zugriff auf Objektvariablen, wenn
Objekte gleicher Klassen betrachtet werden
• Anmerkung: Viele Coding-Guidelines in Unternehmen
verbieten zumindest die ersten beiden Möglichkeiten
• Rat: Wenn Sie bisherige Regeln anwenden, ändern Sie Ihren
Stil nicht !!!
Grundlagen Programmierung
Stephan Kleuker
629
Beispiel: Klasse Punkt im Minimalstil (1/2)
public class Punkt {
private int x;
private int y;
public Punkt (int xWert, int yWert){
x = xWert;
y = yWert;
}
public boolean istNullpunkt(){
if (x==0 && y==0)
return true;
else
return false;
}
Grundlagen Programmierung
Stephan Kleuker
630
Beispiel: Klasse Punkt im Minimalstil (2/2)
public boolean equals(Object o){
if (o==null || !(o instanceof Punkt))
return false;
Punkt p = (Punkt) o;
if (x==p.x && y==p.y)
return true;
else
return false;
}
}
Grundlagen Programmierung
Stephan Kleuker
631
Programmieren ohne echte
Klassen
Grundlagen Programmierung
Stephan Kleuker
X
632
Braucht man Objektorientierung?
• Ja, da so eine wesentliche Möglichkeit zur Strukturierung
von Programmen geschaffen wird
• Objekte sollen Ihre Aufgaben selbst erledigen, keine
Hauptklasse, die alles über get- und set-Methoden steuert
• Nein, da frühere Programmiersprachen (z. B. Fortran, Cobol,
PL/1) keine Objektorientierung haben
• da gab es aber massive Probleme mit großen Programmen
• Nein, da für hardware-nahe Systeme oft keine objektorientierten Sprachen zur Verfügung stehen (aber C)
Grundlagen Programmierung
Stephan Kleuker
X
633
Programme ohne Objektorientierung
• Anschaulich stehen nur Klassenvariablen und
Klassenmethoden zur Verfügung
• Weiterhin gibt es Klassen (Strukturen), die zur Beschreibung
von Datenstrukturen genutzt werden (ähnlich zur
Objektorientierung, Erzeugung einer neuen Struktur mit
new)
public class Punkt{
public int x; // in OO nie erlaubt
public int y; // direkter Kündigungsgrund
}
Grundlagen Programmierung
Stephan Kleuker
X
634
Beispiel: Datenbearbeitung (1/3)
public class Punktbearbeitung{
public static Punkt neuerPunkt(int x, int y){
Punkt ergebnis = new Punkt();
ergebnis.x = x;
ergebnis.y = y;
return ergebnis;
}
public static Boolean gleich(Punkt p1, Punkt p2){
return (p1.x==p2.x && p1.y==p2.y);
}
Grundlagen Programmierung
Stephan Kleuker
X
635
Beispiel: Datenbearbeitung (2/3)
public static Boolean istNullpunkt(Punkt p){
return p.x==0 && p.y==0;
}
public static void verschieben(Punkt p, int dx, int dy){
p.x = p.x + dx;
p.y = p.y + dy;
}
public static void ausgeben(Punkt p){
System.out.print("["+p.x+","+p.y+"]");
}
}
Grundlagen Programmierung
Stephan Kleuker
X
636
Beispiel: Datenbearbeitung (3/3)
public class Main{
public static void punktanalyse(){
Punkt p1;
p1 = Punktbearbeitung.neuerPunkt(6,9);
Punktbearbeitung.ausgeben(p1);
System.out.println("\n"
[6,9]
+Punktbearbeitung.istNullpunkt(p1));
false
Punkt p2 = Punktbearbeitung.neuerPunkt(3,6);
[3,6]
Punktbearbeitung.ausgeben(p2);
false
System.out.println("\n"
true
+Punktbearbeitung.gleich(p1,p2));
false
Punktbearbeitung.verschieben(p2,3,3);
System.out.println(Punktbearbeitung.gleich(p1,p2));
System.out.println((p1==p2));
}
Grundlagen Programmierung
Stephan Kleuker
X
637
Neue Datenstruktur: Liste (1/5)
public class Punktliste{
public Punkt inhalt;
public Punktliste weiter=null;
//
//
//
//
//
ähnlich zu Punkt und Punktbearbeitung wäre auch
eine Aufteilung in Punktliste und
Punktlistenbearbeitung sinnvoll,
generell könnten auch alle Klassenmethoden
in einer Datei (Klasse) stehen.
public static Punktliste neuePunktliste(Punkt p){
Punktliste ergebnis = new Punktliste();
ergebnis.inhalt = p;
return ergebnis;
}
Stephan Kleuker
Grundlagen Programmierung
X
638
Neue Datenstruktur: Liste (2/5)
public static void ausgeben(Punktliste pl){
Punktliste tmp = pl;
System.out.print("[");
while(tmp != null){
Punktbearbeitung.ausgeben(tmp.inhalt);
tmp = tmp.weiter;
}
System.out.println("]");
}
Grundlagen Programmierung
Stephan Kleuker
X
639
Neue Datenstruktur: Liste (3/5)
public static Punktliste anhaengen(Punktliste pl, Punkt p){
Punktliste tmp = pl;
if(tmp == null){
return Punktliste.neuePunktliste(p);
}
while(tmp.weiter != null){
tmp = tmp.weiter;
}
tmp.weiter = Punktliste.neuePunktliste(p);
return pl;
}
}
Grundlagen Programmierung
Stephan Kleuker
X
640
Neue Datenstruktur: Liste (4/5)
// in Main
public static void listenanalyse(){
Punkt p1 = Punktbearbeitung.neuerPunkt(6,9);
Punkt p2 = Punktbearbeitung.neuerPunkt(3,6);
Punktliste pe = null;
Punktliste.ausgeben(pe);
pe = Punktliste.anhaengen(pe,p1);
Punktliste.ausgeben(pe);
// weiter nächste Folie
[]
[[6,9]]
Grundlagen Programmierung
Stephan Kleuker
X
641
Neue Datenstruktur: Liste (5/5)
pe = Punktliste.anhaengen(pe
,Punktbearbeitung.neuerPunkt(6,9));
pe = Punktliste.anhaengen(pe,p2);
Punktliste.ausgeben(pe);
pe = Punktliste.anhaengen(pe,p1);
Punktliste.ausgeben(pe);
p1.x = 9;
Punktliste.ausgeben(pe);
}
}
Grundlagen Programmierung
[[6,9][6,9][3,6]]
[[6,9][6,9][3,6][6,9]]
[[9,9][6,9][3,6][9,9]]
Stephan Kleuker
X
642
Laden und Speichern
Grundlagen Programmierung
Stephan Kleuker
643
Die Klasse File
• Objekt von File wird zur Abfrage von Informationen über
Dateien und Verzeichnisinhalte genutzt
• Die Klasse File enthält z. B. Methoden zum
– Auflisten von Dateien und Verzeichnissen
– Prüfen, ob eine Datei existiert/lesbar/sichtbar schreibbar
– Umbenennen / Löschen von Dateien bzw. Verzeichnissen
• Beispiel: Wir wollen mit einem File arbeiten, dessen relativer
Pfad unter Windows „ .\z\Hi.txt “ lautet
– 1. Möglichkeit:
File f= new File("./z/Hi.txt");
– man muss das Trennsymbol von Unix nutzen
– 2. Möglichkeit:
File f= new File(".\\z\\Hi.txt");
• Backslash (\) leitet in Java Sonderzeichen ein, deshalb \\
• 3. Möglichkeit: systemspezifischer Trenner in Klassenvariable
String tr= File.separator;
File f= new File("."+tr+"z"+tr+"Hi.txt");
Grundlagen Programmierung
Stephan Kleuker
644
Einige Methoden der Klasse File (ohne Parameter)
- testet, ob die Datei lesbar ist
boolean canWrite() - testet, ob die Datei beschreibbar ist
boolean delete() - löscht die Datei (bzw. das Verzeichnis)
boolean exists() - testet, ob die Datei existiert
boolean renameTo(File) - benennt die Datei um
boolean mkdir() - erzeugt ein Verzeichnis
boolean mkdirs() - erzeugt einen Verzeichnisbaum
String[] list() - liefert Liste von Dateien des Verzeichnisses
String getAbsolutePath(), String getPath() - liefert den
entsprechenden Pfad der durch File beschriebenen Datei zurück
String getName() - gibt den Namen der Datei zurück
boolean isFile(), boolean isDirectory() - Abfrage der Dateiart
• boolean canRead()
•
•
•
•
•
•
•
•
•
•
Grundlagen Programmierung
Stephan Kleuker
645
Dateianalyse (1/6)
import java.io.File;
import java.io.IOException;
public class FileAnalyse{
public FileAnalyse(){
this.dialog();
}
public void datei(File datei){
if(datei.canRead()){
System.out.println("lesbar");
}
if(datei.canWrite()){
System.out.println("beschreibbbar");
}
if(datei.canExecute()){
System.out.println("ausfuehrbar");
}
}
Grundlagen Programmierung
Stephan Kleuker
646
Dateianalyse (2/6)
public void dialog(){
EinUndAusgabe io = new EinUndAusgabe();
String datei = "";
File file;
while(!datei.toLowerCase().equals("ende")){
System.out.print("zu untersuchende Datei: ");
datei = io.leseString();
file = new File(datei);
if (!file.exists()){
System.out.println("existiert nicht");
} else {
this.allgemein(file);
if(file.isDirectory()){
this.verzeichnis(file);
} else {
this.datei(file);
}
}
}
Grundlagen
Stephan Kleuker
} Programmierung
647
Dateianalyse (3/6)
public void allgemein(File datei){
try{
System.out.println(" Pfad: "+datei.getAbsolutePath()
+"\n Pfad: " + datei.getCanonicalPath()
+"\n Pfad: " + datei.getPath()
+"\n oben: " + datei.getParentFile()
+"\n versteckt: " + datei.isHidden()
+"\n veraendert: " + datei.lastModified()
+"\n Laenge: " + datei.length());
} catch (IOException e){
System.out.println("Fehler: "+e);
}
}
public void verzeichnis(File datei){
System.out.println("Enthaelt:");
for(String d: datei.list()){
System.out.println(" " + d);
}
Grundlagen
Stephan Kleuker
} Programmierung
}
648
Dateianalyse (4/6)
zu untersuchende Datei: .
Pfad: F:\workspaces\BlueJWork11\FileAnalyse\.
Pfad: F:\workspaces\BlueJWork11\FileAnalyse
Pfad: .
oben: null
versteckt: false
veraendert: 1324637498000
Laenge: 0
Enthaelt:
package.bluej
README.TXT
FileAnalyse.java
EinUndAusgabe.java
EinUndAusgabe.class
EinUndAusgabe.ctxt
FileAnalyse.class
FileAnalyse.ctxt
Grundlagen Programmierung
Stephan Kleuker
649
Dateianalyse (5/6)
zu untersuchende Datei: C:\bootmgr
Pfad: C:\bootmgr
Pfad: C:\bootmgr
Pfad: C:\bootmgr
oben: C:\
versteckt: true
veraendert: 1162461237049
Laenge: 438840
lesbar
ausfuehrbar
Grundlagen Programmierung
Stephan Kleuker
650
Dateianalyse (6/6)
zu untersuchende Datei:
F:\workspaces\BlueJWork11\FileAnalyse\FileAnalyse.java
Pfad: F:\workspaces\BlueJWork11\FileAnalyse\FileAnalyse.java
Pfad: F:\workspaces\BlueJWork11\FileAnalyse\FileAnalyse.java
Pfad: F:\workspaces\BlueJWork11\FileAnalyse\FileAnalyse.java
oben: F:\workspaces\BlueJWork11\FileAnalyse
versteckt: false
veraendert: 1324641712000
Laenge: 1851
lesbar
beschreibbbar
ausfuehrbar
Grundlagen Programmierung
Stephan Kleuker
651
Ein- und Ausgabe in Java
• Basisansatz: Lesen (Input) oder Schreiben (Output) einzelner
Bytes ( machbar, aber für Datentypen, die größer als Byte
sind, unhandlich)
Schreiben
Lesen
• Es handelt sich um Streams
• Streams sind immer unidirektional
• Das Paket java.io stellt verschiedene Klassen zur Verfügung,
die auf dem Streamkonzept basieren
• Hinweis: wir arbeiten hier hauptsächlich mit 8-Bit-Versionen
(gibt gleiche Klassen für Uni-Code, 16 Bit)
Grundlagen Programmierung
Stephan Kleuker
652
Einfaches Schreiben eines Files – Beispiel (1/2)
import java.io.FileOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
public class Analyse {
public static void fileOutput()
throws FileNotFoundException, IOException{
FileOutputStream o = new FileOutputStream("xxx");
String s="Hello again";
for(int i=0; i<s.length(); i++){
o.write(s.charAt(i));
}
o.close();
}
}Grundlagen Programmierung
Stephan Kleuker
653
Einfaches Schreiben eines Files – Beispiel (2/2)
Grundlagen Programmierung
Stephan Kleuker
654
Erinnerung: Sauberes Weiterreichen von Exceptions
• in diesem Abschnitt nur Lesen-Schreiben, fehlt try-finally
public static void fileOutput()
throws FileNotFoundException, IOException{
FileOutputStream o=null;
try{
o = new FileOutputStream("xxx");
String s="Hello again";
for(int i=0; i<s.length(); i++){
o.write(s.charAt(i));
}
}
finally{
if(o!=null){
o.close();
}
}
Stephan Kleuker
655
Grundlagen
} Programmierung
Einfaches Schreiben eines Files - Analyse
FileOutputStream o = new FileOutputStream("xxx");
String s="Hello again";
for(int i=0; i<s.length(); i++){
o.write(s.charAt(i));
}
o.close();
•
•
•
•
Im Konstruktor wird ein Filename (oder File) übergeben
Es kann nur Byte-Weise geschrieben werden
nur verschiedene einfache Varianten von write() verfügbar
Generell ist es wichtig, beim Arbeiten mit Files diese am
Ende zu schließen ( close() )
• es gibt verschiedene Konstruktoren, z.B.:
public FileOutputStream(String name, boolean append)
Grundlagen Programmierung
Stephan Kleuker
656
Einfaches Lesen eines Files
FileInputStream i= new FileInputStream("xxx");
int in = i.read();
while(in!=-1) {
System.out.print((char)in);
in=i.read();
}
i.close();
• Alle Bytes werden grundsätzlich als int eingelesen, müssen
bei Bedarf in byte oder char gewandelt werden
• Das File-Ende wird durch den Wert -1 erkannt
• Vorgestelltes Lesen und Schreiben ineffizient, da jede
Methode erneut auf das Betriebssystem zugreifen muss
Grundlagen Programmierung
Stephan Kleuker
657
Beispiel: Datei kopieren
// mehrere Imports weggelassen
public class Copy{
public static void main(String[] s) throws IOException{
FileInputStream in = new FileInputStream(s[0]);
FileOutputStream out= new FileOutputStream(s[1]);
int zeichen=0;
while(zeichen!=-1){
zeichen=in.read();
if (zeichen!=-1) {
out.write(zeichen);
}
}
in.close();
out.close();
}
}Grundlagen Programmierung
Stephan Kleuker
658
Schnellere Ein- und Ausgabe in Java
• einzulesende (bzw. auszugebende) Daten zwischenpuffern
und bei vollem Puffer verarbeiten
Ausgabe
Puffer
out(a) a
out(b)
a b
out(c)
a b c
out(d)
abc
d
Grundlagen Programmierung
Stephan Kleuker
659
Die Klasse BufferedOutputStream
• Daten werden in einen Puffer geschrieben, dessen Inhalt nur
dann in den Stream geschrieben wird, wenn er voll ist
BufferedOutputStream o = new BufferedOutputStream(
new FileOutputStream("xxa"),4);
String s="Hello again";
for(int i=0;i<s.length();i++) {
o.write(s.charAt(i));
}
o.close();
• BufferedOutputStream ermöglicht Daten zu schreiben, ohne
bei jeden Aufruf physikalisch auf das Gerät zuzugreifen
• explizites Leeren des Puffers mit flush()
Grundlagen Programmierung
Stephan Kleuker
660
Die Klasse BufferedInputStream
• Daten werden blockweise in einen Puffer gelesen, auf dem
bei jeder Leseaktion zugegriffen wird
BufferedInputStream i= new BufferedInputStream(
new FileInputStream("xxa"),4);
int in = i.read();
while(in!=-1){
System.out.print((char)in);
in=i.read();
}
• BufferedInputStream ermöglicht Daten zu lesen, ohne bei
jeden Aufruf physikalisch auf das Gerät zuzugreifen
• BufferedInputStream enthält die Methoden
• mark() zum markieren einer Position im Puffer
• reset() zur Zurückführung des Pufferzeigers auf die
letzte Markierung
Grundlagen Programmierung
Stephan Kleuker
661
Beispiel
public static void bufferedIO() throws IOException{
BufferedOutputStream o = new BufferedOutputStream(
new FileOutputStream("xxa"),4);
String s="Hello again";
for(int i=0;i<s.length();i++){
o.write(s.charAt(i));
}
BufferedInputStream i = new BufferedInputStream(
new FileInputStream("xxa"),4);
int in = i.read();
while(in!=-1){
Ausgabe:
System.out.print((char)in);
in=i.read();
Hello ag
}
i.close();
o.close();
}
am Ende aber:
Grundlagen Programmierung
Stephan Kleuker
662
mächtigeres Arbeiten mit Files
• Grundsätzlich kann man beliebige Speicher- und
Lesefunktionalitäten auf FileInputStream und
FileOutputStream aufbauen
• Da sich diese Entwicklung komplexer Speicher- und
Leseansätze sich häufig wiederholt, gibt es in der
Klassenbibliothek verschiedene mächtigere Klassen zur
Zusammenarbeit mit Files
• Ein Ansatz wäre, von den genannten Klassen zu erben und
die so zu erweitern
• Java-Ansatz ist Aggregation, die mächtigeren Klassen haben
ein Objekt der oben genannten Klasse als Objektvariable
und verwalten den Zugriff
Grundlagen Programmierung
Stephan Kleuker
663
Die Klasse DataOutputStream
• Mit Hilfe eines DataOutputStreams können einfache Datentypen
binär geschrieben werden
•
•
•
•
•
•
•
•
writeBoolean();
writeByte();
writeChar();
writeDouble();
writeFloat();
writeInt();
writeLong();
writeShort();
• Konstruktor erwartet einen Outputstream als Parameter
public DataOutputStream(OutputStream os);
• Analog existiert DataInputStream, mit zusätzlicher Methode
readLine() zum Einlesen eines Strings
Grundlagen Programmierung
Stephan Kleuker
664
Beipiel (1/2)
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class Punkt {
private int x;
private int y;
public Punkt(int a, int b) {this.x = a; this.y = b;}
public void speichern(DataOutputStream o)
throws IOException{
o.writeInt(this.x);
o.writeInt(this.y);
}
public static Punkt lesen(DataInputStream i)
throws IOException{
return new Punkt(i.readInt(),i.readInt());
}
Grundlagen Programmierung
Stephan Kleuker
665
Beispiel (2/2)
public String toString(){
return "X: "+this.x+" Y: "+this.y;
}
}
public static void main(String[] args)
throws IOException {
DataOutputStream o= new DataOutputStream(
new FileOutputStream("aab"));
Punkt p1= new Punkt(300,400);
Punkt p2= new Punkt(500,600);
p1.speichern(o);
p2.speichern(o);
o.close();
DataInputStream i= new DataInputStream(
new FileInputStream("aab"));
Punkt p3= Punkt.lesen(i);
Punkt p4= Punkt.lesen(i);
Ausgabe:
System.out.println(p3+"\n"+p4);
X: 300 Y: 400
i.close();
X: 500 Y: 600
}Grundlagen Programmierung
Stephan Kleuker
666
Ein- und Ausgabe von Objekten (1/2)
• Werden die Werte der Datenfelder eines Objektes in einen
Bytestrom überführt, der sich rekonstruieren lässt, so
spricht man von Objektserialisierung
• Java stellt dazu zwei Klassen zur Verfügung
ObjectOutputStream:
public writeObject(Object o) throws IOException
ObjectInputStream:
public final Object readObject() throws
OptionalDataException, ClassNotFoundException,
IOException
• Objekte werden beim Schreiben und Lesen rekursiv
abgearbeitet (d. h. immer alle Objektvariablen)
Grundlagen Programmierung
Stephan Kleuker
667
Ein- und Ausgabe von Objekten (2/2)
• Schnittstelle Serializable dient zur Kennzeichnung, dass ein
Objekt einer Klasse serialisierbar ist
• Schnittstelle selbst deklariert keine Methoden
• Klasse nur serialisierbar, wenn alle Objektvariablen serialisierbar
• bis auf einige graphische Klassen sind alle wichtigen Klassen der
Klassenbibliothek serialisierbar
• grundsätzlich ist "implements Serializable" immer gute Idee
• Objekt-Serialisierung:
– Vorteile: schnell, recht kompakte Daten
– Nachteile: mit neuen Klassenversionen nicht mehr nutzbar,
können von keinen anderen Programmen gelesen werden
Grundlagen Programmierung
Stephan Kleuker
668
Serialisierungsbeispiel (1/3)
import
import
import
import
import
import
java.io.Serializable;
java.io.IOException;
java.io.FileOutputStream;
java.io.ObjectOutputStream;
java.io.FileInputStream;
java.io.ObjectInputStream;
public class Person implements Serializable{
private String name;
private String vorname;
private static final String DATEI = "text.txt";
private static final long serialVersionUID = 2L;
public Person (String n, String v){
this.name = n;
this.vorname = v;
}
@Override
public String toString(){
return this.vorname+" "+this.name;
} Programmierung
Grundlagen
Stephan Kleuker
669
Serialisierungsbeispiel (2/3)
public static void schreiben() throws IOException{
Person pers1 = new Person ("Maier", "Anja");
ObjectOutputStream out=
new ObjectOutputStream (new FileOutputStream(DATEI));
out.writeObject (pers1);
out.writeObject (new Person ("Schulz", "Oleg"));
out.writeObject ("Hallo");
out.close();
}
public static void lesen() throws IOException,
ClassNotFoundException{
ObjectInputStream in =
new ObjectInputStream (new FileInputStream (DATEI));
for(int i=0; i<3; i=i+1){
Object o = in.readObject(); // sonst casten
System.out.println(o);
}
in.close();
Grundlagen
Programmierung
Stephan Kleuker
670
}
Serialisierungsbeispiel (3/3)
public static void main(String[] s)throws IOException,
ClassNotFoundException{
Person.schreiben();
Person.lesen();
}
Grundlagen Programmierung
Stephan Kleuker
671
SerialVersionUID
• serialisierte Objekte typischerweise nur mit der gleichen
Klasse einlesbar, die auch zum Schreiben genutzt wurde
• Änderungen an Objektvariablen macht serialisierte Objekte
nicht nutzbar
• Lösung: Konverter schreiben
• Lösung: XMLEncoder und XMLDecoder nutzen
• woran erkennt neue Klasse, dass zu alte Objekte gelesen
werden soll?
– Nutzung eine speziellen vorgegebenen Klassenvariable
serialVersionUID
– Nummer wird mit serialisiert
– stimmt sie beim Laden nicht überein, gibt es
Fehlermeldung
Grundlagen Programmierung
Stephan Kleuker
672
serialVersionUID – Warning in Java
• typische Eclipse-Meldung
• Lösungsvorschläge in Eclipse (Linksklick)
• im ersten Fall beginnt Nummerierung mit 1 (1L für long)
• sonst zufällige Nummer
Grundlagen Programmierung
Stephan Kleuker
673
Beispielproblemfall
public class Person implements Serializable{
private String name;
private String vorname;
private static final String DATEI = "text.txt";
private static final long serialVersionUID = 1L;
• Person.schreiben()
• Änderung:
private static final long serialVersionUID = 2L;
• Person.lesen()
Grundlagen Programmierung
Stephan Kleuker
674
transient
Das Schlüsselwort transient:
Unterdrückung von Objektvariablen beim
Speichern
public class person implements Serializable{
private String name;
private String vorname;
private transient int alter;
....
}
Grundlagen Programmierung
Stephan Kleuker
675
Erinnerung: Uni-Code
• Java als Sprache des Internets nutzt Uni-Code
• Uni-Code ist echte Obermenge von ASCII und ISO 8859-1
(Latin 1)
• In Java gibt es 8-Bit-Klassen (etwas schneller, einfacher)
und 16-Bit-Klassen zum File-Handling (und Klassen, um 8Bit-Welt mit 16-Bit-Welt zu verknüpfen)
• In Java hat Byte-Stream und Character-Stream Klassen
Byte-Stream
Character-Stream
FileInputStream
FileReader
FileOutputStream
FileWriter
BufferedInputStram
BufferedReader
BufferedOutputStream
BufferedWriter
Grundlagen Programmierung
Stephan Kleuker
676
Klassenvariablen von System
public static final InputStream in
The "standard" input stream. This stream is already open and
ready to supply input data. Typically this stream corresponds
to keyboard input or another input source specified by the
host environment or user.
public static final PrintStream out
The "standard" output stream. This stream is already open
and ready to accept output data. Typically this stream
corresponds to display output or another output destination
specified by the host environment or user. See the println
methods in class PrintStream.
public static final PrintStream err
The "standard" error output stream. This stream is already
open and ready to accept output data.
Typically this stream corresponds to display output or another
output destination specified by the host environment or user.
Grundlagen Programmierung
Stephan Kleuker
677
Einlesen von der Tastatur
public class EinUndAusgabe {
public String leseString(){
String ergebnis;
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
try {
ergebnis=in.readLine();
} catch (IOException e) {
ergebnis="";
}
return ergebnis;
}
public int leseInt(){
int erg;
try {
erg=Integer.decode(leseString()).intValue();
} catch (NumberFormatException e) {
erg=-1;
}
return erg;
Stephan Kleuker
Grundlagen
Programmierung
}
678
Aufzählungen
Grundlagen Programmierung
Stephan Kleuker
679
Aufzählungen für Anfänger und Klassiker
public class Programmiererfahrung {
private String[] stufen={"nicht vorhanden",
"Grundkenntnisse","alte Projekterfahrung",
"Projektmitarbeiter", "Experte"};
private int stufenwert=0;
...
}
public class Erfahrung {
public final static int NICHT_VORHANDEN=0;
public final static int GRUNDKENNTNISSE=1;
public final static int ALTE_PROJEKTERFAHRUNG=2;
public final static int PROJEKTMITARBEITER=3;
public final static int EXPERTE=4;
}
Zugriff mit:
int meineErfahrung= Erfahrung.NICHT_VORHANDEN;
Grundlagen Programmierung
Stephan Kleuker
680
Aufzählungen mit Enum
• Enum ist spezielle Art von Klasse (kann damit Methoden
beinhalten)
• Werte als einfache Texte, beginnend mit Buchstaben
aufschreiben
public enum Erfahrung {
NICHT_VORHANDEN,
GRUNDKENNTNISSE,
ALTE_PROJEKTERFAHRUNG,
PROJEKTMITARBEITER,
EXPERTE
}
Grundlagen Programmierung
Stephan Kleuker
681
Aufzählungen mit Enum - Nutzung
public class Spielerei {
public static void main (String[] s){
Erfahrung ich= Erfahrung.NICHT_VORHANDEN;
System.out.println(ich);
for(Erfahrung e: Erfahrung.values()){
System.out.println(e);
}
NICHT_VORHANDEN
}
NICHT_VORHANDEN
}
GRUNDKENNTNISSE
ALTE_PROJEKTERFAHRUNG
PROJEKTMITARBEITER
EXPERTE
Grundlagen Programmierung
Stephan Kleuker
682
Weitere Methoden von enum-“Klassen“ (1/2)
Erfahrung ich= Erfahrung.NICHT_VORHANDEN;
System.out.println(ich.getClass());
System.out.println(ich.compareTo(Erfahrung.NICHT_VORHANDEN));
System.out.println(ich.compareTo(Erfahrung.EXPERTE));
System.out.println(ich.equals(0));
System.out.println(ich.equals(1));
System.out.println(ich.equals(Erfahrung.NICHT_VORHANDEN));
class Erfahrung
0
-4
false
false
true
Grundlagen Programmierung
Stephan Kleuker
683
Weitere Methoden von enum-“Klassen“ (2/2)
System.out.println(ich.getDeclaringClass());
System.out.println(ich.name());
System.out.println(ich.ordinal());
System.out.println(Erfahrung.valueOf("EXPERTE"));
try{
System.out.println(Erfahrung.valueOf("Experte"));
}catch (IllegalArgumentException e){
System.out.println(e);
}
System.out.println(Erfahrung.valueOf(Erfahrung.class,"EXPERTE"));
class Erfahrung
NICHT_VORHANDEN
0
EXPERTE
java.lang.IllegalArgumentException: No enum const Experte
EXPERTE
Grundlagen Programmierung
Stephan Kleuker
684
Objekte von enum-Klassen
• Mit enum werden besondere Klassen definiert, sind final
(keine Vererbung möglich), keinen von außen nutzbaren
Konstruktor
• Durch Erfahrung ich= Erfahrung.NICHT_VORHANDEN; erhält
man ein Objekt der Klasse Erfahrung
• D. h. Enum-Klassen können zusätzlich „normale“
Exemplarmethoden und Exemplarklassen enthalten (auch
z. B. toString())
• Klassenmethodenaufruf Erfahrung.klassenmethode();
• Methodenaufruf: ich.exemplarmethode();
Grundlagen Programmierung
Stephan Kleuker
685
Erweiterte Möglichkeiten mit enum (1/2)
• Aufzählungswerte können Parameter haben, die im
Konstruktor verarbeitet werden
public enum Coin {
PENNY(1),
NICKEL(5),
DIME(10),
QUARTER(25);
private final int value;
Coin(int value) {
this.value = value;
}
public int value() {
return value;
}
}
Grundlagen Programmierung
Stephan Kleuker
686
Erweiterte Möglichkeiten mit enum (2/2)
public class CoinAnalyse {
private enum CoinColor { COPPER, NICKEL, SILVER }
public static void main(String[] args) {
for (Coin c : Coin.values()){
System.out.println(c +":"+c.value()+"c "+color(c));
}
}
PENNY:1c COPPER
private static CoinColor color(Coin c) { NICKEL:5c NICKEL
DIME:10c SILVER
switch(c) {
case PENNY: return CoinColor.COPPER; QUARTER:25c SILVER
case NICKEL: return CoinColor.NICKEL;
case DIME:
case QUARTER: return CoinColor.SILVER;
default:
throw new AssertionError("Unknown coin: " + c);
}
}
}Grundlagen Programmierung
Stephan Kleuker
687
Kartenstapel (1/3)
public enum Farbe {
KARO, HERZ, KREUZ, PIK;
@Override
public String toString(){
switch(this){
case KARO: return("Karo");
case HERZ: return("Herz");
case KREUZ: return("Kreuz");
case PIK: return("Pik");
default: return("");
}
}
}
Prof. Dr. Stephan Kleuker
Stephan Kleuker
688
Kartenstapel (2/3)
public enum Wert {
SIEBEN("7"), ACHT("8"), NEUN("9"), ZEHN("10"),
BUBE("Bube"), DAME("Dame"), KOENIG("Koenig"), AS("As");
private String text;
Wert(String text){
this.text=text;
}
@Override
public String toString(){
return text;
}
}
Prof. Dr. Stephan Kleuker
Stephan Kleuker
689
Kartenstapel (3/3)
public class Karte {
private Farbe farbe;
private Wert wert;
...
public class Kartenstapel {
private ArrayList<Karte> stapel=new ArrayList<Karte>();
public static Kartenstapel gibAlleKarten(){
Kartenstapel k= new Kartenstapel();
for(Farbe f: Farbe.values())
for(Wert w: Wert.values())
k.add(new Karte(f,w));
return k;
}
//...
Prof. Dr. Stephan Kleuker
Stephan Kleuker
690
Herunterladen