ProPra-Vorkurs

Werbung
EINFÜHRUNG IN DIE
PROGRAMMIERUNG
FORTGESCHRITTENE KONZEPTE
Tobias Witt
26.03.2014
•
[email protected]
•
25.12.01.30
•
Bürozeiten: 09 Uhr - 12 Uhr
FEHLERBEHANDLUNG
KLASSISCHER ANSATZ
•
Fehlercode als Rückgabewert von Methoden
‣
String ➜ Fehlercode als String
‣
int ➜ Fehlercode als Integer
‣
List ➜ ???
‣
void ➜ ???
KLASSISCHER ANSATZ
PROBLEME
•
Fehlerbehandlung stets direkt
•
Abfrage von Rückgabewert nötig
‣
Verschiedene Fehler - verschiedene FehlerRückgabewerte
•
Einschränkung des Werte-Bereichs der Methode
AUSNAHMEN - EXCEPTIONS
•
Fehler als „Ausnahme“ explizit oder implizit
ausgelöst
•
Fehlerursache „wirft“ Exception
•
Fehlerbehandler „fängt“ Exception
AUSNAHMEN - EXCEPTIONS
•
Geprüfte Ausnahmen (Checked Exceptions)
‣
•
Ungeprüfte Ausnahmen (Unchecked Exceptions)
‣
•
Müssen behandelt werden
Müssen nicht unbedingt behandelt werden
Jede nicht behandelte Exception bricht das Programm ab!
AUSNAHMEN BEISPIELE
NullPointerException
Methode wird auf null aufgerufen
ArrayIndexOutOfBoundsException
Zugri# auf nicht existierenden Array-Index
ClassCastException
Casting nicht möglich
NumberFormatException
z.B. bei Integer.parseInt("bogus")
FileNotFoundException
Dateiname existiert nicht
Exception KLASSE
•
Geprüfte Exceptions:
‣
•
Erben von Exception
Ungeprüfte Exceptions:
‣
Erben von RuntimeException
AUSNAHMEN BEHANDELN
Ungeprüfte NumberFormatException
public class Spiel {
public static void main(String[] args) {
int a = Integer.parseInt("42");
FileInputStream f =
new FileInputStream("datei");
}
}
Unhandled exception: java.io.FileNotFoundException
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
FileInputStream f;
try {
f = new FileInputStream("datei");
} catch (FileNotFoundException e) {
f = createFile("datei");
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int firstByte = f.read();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Unhandled exception: java.io.IOException
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int firstByte = f.read();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace()
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
int firstByte = f.read();
} catch (FileNotFoundException |
IOException e) {
e.printStackTrace();
}
}
}
AUSNAHMEN BEHANDELN
public class Spiel {
public static void main(String[] args) {
try {
FileInputStream f =
new FileInputStream("datei");
// ...
} catch (Exception e) {
} finally {
f.close();
}
}
Unhandled exception: java.io.IOException
}
AUSNAHMEN BEHANDELN
try with resources (Java 7)
public class Spiel {
public static void main(String[] args) {
try (FileInputStream f =
new FileInputStream("datei")) {
// ...
} catch (Exception e) { implements AutoClosable
}
}
}
AUSNAHMEN BEHANDELN II
public class LevelDatei implements AutoCloseable {
private File levelDatei;
public LevelDatei(String fileName) throws IOException {
levelDatei = createFile(fileName);
}
private File createFile(String fileName) throws IOException {
// erstelle Datei
}
public void schreibeLevel() throws IOException {
// schreibe Level in Datei
}
@Override
public void close() throws Exception {
// schließe Datei
}
}
AUSNAHMEN BEHANDELN II
public class Spiel {
public static void main(String[] args) {
try(LevelDatei ld = new LevelDatei("level1.lvl")) {
ld.schreibeLevel();
} catch (IOException) {
e.printStackTrace();
}
}
}
AUSNAHMEN ERZEUGEN
public class Wurm {
public class WurmLebenException extends
IllegalArgumentException {
}
private int leben;
public Wurm(int leben) {
if (leben <= 0) {
throw new WurmLebenException(
"Leben muss größer 0 sein");
}
this.leben = leben;
}
}
NEBENLÄUFIGKEIT
MAIN THREAD
Start
•
main-Methode im Main
Thread
•
Sequentielle Ausführung
innerhalb jedes Threads
•
Anweisungen blockieren &
warten
Anweisung 1
Anweisung 2
Anweisung 3
Ende
MEHRERE THREADS
•
•
•
Asynchrone Ausführung
von Main Thread und
Thread 2
Gefahr bei Verwendung
gleicher Daten
Anweisungen blockieren &
warten nur innerhalb eines
Threads
Main Thread
Start
Thread 2
Anweisung 1
Start
Anweisung 2
Anweisung 4
Anweisung 3
Ende
Anweisung 5
Ende
THREADS STARTEN
public class Spiel {
public static void main(String[] args) {
final String string = " du";
Thread t = new Thread(new Runnable() {
@Override
Closure
public void run() {
try {
„main-Methode“
des Threads
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(string);
}
});
t.start();
System.out.print("Hallo");
}
}
JAVA 8
public class Spiel {
public static void main(String[] args) {
final String string = " du";
Thread t = new Thread(()-> {
Lambdatry {
Expression
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(string);
});
t.start();
System.out.print("Hallo");
}
}
ERGEBNIS?
Main Thread
Start
Thread 2
Starte Thread
$ java Spiel
Hallo du
Gebe
“Hallo“ aus
Ende
Start
Warte 2s
Gebe “ du“
aus
Ende
TIMING-PROBLEME
Korrektes Ergebnis?
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownloadAsynchron();
String ergebnis = dd.getErgebnis();
}
}
TIMING-PROBLEME
Lösung?
NEIN!!!!!
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownloadAsynchron();
Thread.sleep(2000);
String ergebnis = dd.getErgebnis();
}
}
CALLBACK
public interface DownloadListener {
public void fertig(String ergebnis);
}
public class DatenDownloader {
public void starteLangenDownload(DownloadListener l) {
new Thread(() -> {
// download...
String ergebnis = "ergebnis";
l.fertig(ergebnis);
}).start();
}
}
CALLBACK IMPLEMENTIEREN
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownload(new DownloadListener() {
@Override
public void fertig(String ergebnis) {
// verarbeite ergebnis
}
});
}
}
JAVA 8
LambdaExpression mit Parameter
public class Spiel {
public static void main(String[] args) {
DatenDownloader dd = new DatenDownloader();
dd.starteLangenDownload((String ergebnis) -> {
// verarbeite ergebnis
});
}
}
GEMEINSAM GENUTZTE
DATEN
•
•
Thread 1
Thread 2
Start
Start
konto1 -= 9
konto1 -= 2
konto2 += 9
konto2 += 2
Ende
Ende
konto1 = 10
konto2 = 0
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
MÖGLICHE ERGEBNISSE
Gültig
konto1 = 1, konto2 = 9
Gültig
konto1 = 8, konto2 = 2
Ungültig
konto1 = -1, konto2 = 11
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
public class Spiel {
static int konto1 = 10;
static int konto2 = 0;
Spiel
während Methode gesperrt
synchronized static void transfer(int betrag) {
if (konto1 - betrag >= 0) {
// Zeit vergeht
konto1 -= betrag;
konto2 += betrag;
}
}
public static void main(String[] args) {
new Thread(() -> { transfer(2); }).start();
new Thread(() -> { transfer(9); }).start();
}
}
DEADLOCK
DEADLOCK
Thread 1
Thread 2
Sperre auf a
Sperre auf b
Sperre auf b
Sperre auf a
Entferne Sperre auf a
Entferne Sperre auf b
Entferne Sperre auf b
Entferne Sperre auf a
TEST DRIVEN DEVELOPMENT
TDD
•
Software in ständiger Metamorphose
•
Tests zwingend erforderlich
‣
•
Egal ob von Menschen oder automatisch
Test Driven Development: Tests vor der
Implementierung implementieren
BOWLING GAME KATA
1
4
5
4
5
14
6
5
29
0
49
60
1
61
7
6
77
2
97
117
6
133
•
10 Frames
•
Spare: 10 Pins in 2 Würfen: Nächster Wurf doppelt
•
Strike: 10 Pins in 1 Wurf: Nächsten 2 Würfe doppelt
•
Strike oder Spare im letzten Frame: 1-2 Würfe extra
ANFORDERUNGEN
•
Game Klasse
‣
public void roll(int pins);
-
‣
Simuliert einen Wurf
public int score();
-
Gibt die Gesamtpunktzahl zurück
BEGINN
•
•
Erstelle neues Projekt
‣
File ➜ New Project ➜ Java
‣
Name: BowlingGame
Erstelle GameTest Klasse
‣
Rechtsklick auf src ➜ New ➜ Java Class
‣
Name: de.hhu.propra.bowlinggame.GameTest
BILDQUELLEN
Bild
Quelle
Exceptions, Threads
http://geek-and-poke.com/
Deadlock
http://openbook.galileocomputing.de/javainsel9/bilder/
365_java_09_004.gif
TDD
http://www.projectcartoon.com/cartoon/353819
Herunterladen