So, liebe Studierende,
der Timer ist auf 45 Minuten gestellt, schönen guten Tag.
Als ich die Folien für diese Vorlesung zusammengestellt habe,
dachte ich, okay, du machst jetzt folgendes.
Du nimmst dein eigenes Lecture-to-go auf mit so einem Selfie,
anderthalb Stunden und dann spielst du das hier in doppelter Geschwindigkeit ab.
Sollen sie doch sehen, wie sie klarkommen.
Dann können sie das ja zu Hause in halber Geschwindigkeit abstellen
, abspielen.
Ich habe mich dann dagegen entschieden
Es wäre doch zu viel Technik, wie sie sehen werden,
wenn sie sich die Folien anschauen, die ich im Internet hochgeladen habe.
Das ist nur ungefähr die Hälfte der Fools. Nein,
das werden sie nicht sehen. Was sie sehen werden,
ist eine Menge von Folien und das sind ungefähr doppelt so viele
wie die, die ich zeigen werde. Ich hoffe,
es gelingt mir trotzdem einen roten Faden durch die zwei Themen zu finden,
einen roten Pfad, einen roten Pfad zu finden,
der einen für sie nachvollziehbaren Weg zu gehen durch die zwei Themen,
die wir heute behandeln,
gemeinsam.
Das erste ist das Thema Fehler
Und wie geht man mit Fehlern um? Unter besonderer Berücksichtigung
einer Objektorientierten Programmiersprache, Java. Und das zweite Thema wird sein,
jetzt sind sie sozusagen nach unserer Einschätzung reif,
sich mal etwas zurückzulehnen und zu schauen,
was mache ich eigentlich, wenn ich Programme schreiben muss,
Aufgaben vor mir sehe, an denen mehr als,
sagen wir mal, so ein Dutzend Klassen beteiligt sind.
Gibt es noch über das, was Sie bis jetzt kennen,
weitergehende Strukturierungsmaßnahmen für, projektorientierte Programme.
Und wenn ich das so einleite, dann denke ich,
ist schon klar, die Antwort darauf lautet, ja,
zu dem Thema wird Ihnen, wenn das nicht schon klar ist,
was da steht bezüglich der Umstellung des Übungskonzeptes.
Wir hatten ja am Anfang des Semesters auch schon darüber gesprochen,
dass das so dann in etwas größte,
dass Sie ab einem bestimmten Zeitpunkt, der jetzt gekommen ist,
in etwas größeren Teams arbeiten werden.
Also die Phase 1 der Übungen ist beendet.
Ab jetzt geht es in die Laborphase 2,
in der sie von uns angehalten werden, genötigt werden,
in Vierergruppen zu arbeiten.
Und die Bearbeitungszeit verändert sich. Falls Sie dazu nachher noch Fragen haben,
steht Ihnen Fred sicherlich für Details noch zur Verfügung.
So, nun zu dem inhaltlichen Thema heute, davon gesagt, zwei Themen.
Erstes Thema ist Fehlerbehandlung mit sogenannten Exceptions, Exceptions und Ausnahmen
, was das ist, wie man damit umzugehen hat.
Sie sehen die einzelnen Punkte, die ich da für sie
vorbereitet habe
Eine Eigenschaft dieses Themas ist, dass sie da viele von den Techniken Hilfsmitteln kennenlernen werden,
die wir so in den vergangenen Wochen und aber auch schon im letzten Semester kennengelernt haben.
Zunächst mal so eine beliebte Technik,
um sich so einem großen Konzept wie Fehler zu nähern,
ist, dass man das aufteilt, so nach dem Muster, dividd at imperateile und herrsche.
Also wir reden nicht über Fehler als solche,
sondern wir reden im folgenden, wenn wir über Fehler sprechen,
Also wir über Fehler sprechen, über zwei Arten von Fehlern,
die wir unterscheiden können und mit denen wir auch in den Programmen,
die wir schreiben, unterschiedlich umgehen wollen,
beziehungsweise für die wir unterschiedliche Techniken haben,
mit denen wir damit umgehen wollen.
Das sind die sogenannten Entwicklerfehler, Entschuldigung, Entwicklungsfehler und die Umgebungsfehler.
Entwicklungsfehler sind die Fehler, die sie machen.
Und es ist so, wir machen Fehler, nein,
die machen es, doch machen sie.
Und das ist ja wie im Straßenverkehr,
nicht man selbst ist das Problem,
sondern die anderen sind das Problem
Problem. Also sie werden jetzt Techniken kennenlernen, mit denen sie sogenannte Entwicklungsfehler,
wie sie mit Entwicklungsfehlern beherrschbar umgehen können. Diese Fehler passieren,
das ist, irren ist menschlich und wir müssen uns bei der Konstruktion der Programme,
die wir schreiben, darauf vorbereiten, dass solche Fehler passieren,
um die Robustheit unserer Programme zu erhöhen.
Was wir nicht wollen, ist, dass die Menschen,
die mit den Programmen, die sie schreiben, die wir schreiben,
dass die Fehlermeldungen bekommen, mit denen die nichts anfangen können.
Pojogramme abbrechen und die Programme sich in einem Zustand befinden,
nicht die Programme, aber die Daten, die diese Programme hinterlassen,
die inkonsistent sind, weil diese Art von Umgang mit Fehlern,
insbesondere Entwicklungsfehlern, ist nicht effizient.
Die zweite Art von Fehler, sogenannte Umgebungsfehler, Fehler,
die natürlich in gewisser Weise Softwareentwickler zu verantworten haben,
aber nicht nur Softwareentwickler sind dafür verantwortlich, das Umgebungsfehler auftreten.
Das können auch Baggerfahrer sein. Baggerfahrer,
die nach bestem Wissen und Gewissen ihre Schaufel nur dort ansetzen,
wo sie vermuten, dass dort kein Kabel liegt,
auf das sie angewiesen sind, aber Dinge passieren auch dort.
Und das ist nun nicht etwas,
was sie bei der Softwareentwicklung berücksichtigen können,
weil ob sie jetzt ein Baggerfahrer ist oder ein Meteorit,
der einschlägt, also die Anzahl der Möglichkeiten,
dass in ihrer Umgebung etwas schief läuft,
sind wahrscheinlich noch unendlich vielfältiger als das,
was sie selbst
anrichten können
Auf diese Art von Fehlern müssen wir möglicherweise anders reagieren.
So, mal so, das war jetzt so eine intentionale,
der intentionale Versuch, Fehler zu kategorisieren.
Hier sehen Sie die Extension, also ein paar Beispiele dafür,
was sind Entwicklungs- und Umgebungsfehler und um es ihnen einfacher zu machen,
habe ich das auch mal gleich da dran geschrieben.
Also das E steht für Entwicklungsfehler und U ist ein Fehler,
der als Umgebungsfehler charakterisiert wird.
Ich nehme mal für jede Art von Fehler eins aus.
Ein Klient hält sich bei der Anforderung einer Dienstleistung
nicht an die Vorbedingungen vor
Vorbedingungen, Vorbedingungen, da war doch was, genau,
da war was. Eine Operation macht explizit, welche Bedingungen
vom Klienten eingehalten werden müssen, um sie aufrufen zu können.
Wenn der Klient sich nicht dran hält, dann ist das
ein Fehler, ein Entwicklungsfehler. Und zwar hat der Klient
mal was anderes als Parameter übergeben oder auch nicht übergeben als das,
was die Vorbedingungen einer Operation explizit ausweist.
Das ist ein Entwicklungsfehler und mit Hilfe des Vertragsmodells können wir auch schon sagen,
wer ist schuld, dass dieser Fehler ausgelöst wird und was wir diese Vorlesung lernen werden,
ist, kann man im Programm damit umgehen,
dass dieser Entwicklungsfehler nicht nur, also von der Verantwortung,
sondern auch von der Art des Umgangs so behandelt wird,
dass das Programm verantwortungsvoll endet.
Verantwortungsvoll bedeutet hier, dass die Daten, die dieses Rückprogramm,
insbesondere, dass die Daten, die dieses Programm verarbeitet,
sich nicht in einem inkonsistenten Zustand befinden,
obwohl ein Entwicklungsfehler aufgetreten ist.
Ein Beispiel für einen Umgebungsfehler, nun nehmen wir gleich,
was da drunter ist für den Zugriff,
auf eine Website hat der Browser keinen Zugang zum Internet
Ja, wenn das Internet einen Teil meiner Umgebung ist und es steht gerade mal
nicht zur Verfügung, dann muss ich darauf reagieren können.
Dieses Reagieren sollte nicht auf der Ebene des Benutzers stattfinden,
der seinen Computer anschreit oder seinen Browser, was auch immer,
sondern dieser Umgebungsfehler sollte im Programm registriert werden und dann sollte eine nachvollziehbare Handlung daraus folgen.
Was den Umgang mit diesen verschiedenen Arten von Fehlersituationen anbetrifft,
also möchte ich jetzt hier an der Stelle eigentlich
nur auf einen Punkt eingehen
Wenn so ein Fehler auftritt und der kann jetzt,
wie sie das da oben sehen, auf unterschiedlichen Stellen,
kann der wahrgenommen werden und es kann auch an unterschiedlichen Stellen darauf reagiert werden,
stellt sich bei der Fehlerbehandlung und das sind die zwei Fragen,
die ich jetzt so im Weiteren hier beantworten werde,
wie kann sich ein Klient auf mögliche Fehler einstellen?
Was soll er dann tun, damit dieses Programm mit einem konsistenten Zustand bleibt,
beziehungsweise der in einen konsistenten Zustand überführt wird,
beziehungsweise in einem konsistenten Zustand beendet wird und dann noch die Frage,
auf die unterschiedlichen Fehlerarten.
Und die habe ich ja jetzt erstmal so auseinander differenziert.
Kann er auf diese unterschiedlichen Fehlerarten auch unterschiedlich reagieren und
welche Möglichkeiten stehen Ihnen da eigentlich zur Verfügung?
Diese Art von Überlegung auf Fehler reagieren zu müssen,
ist jetzt, also ist nichts Neues im Sinne von,
man hat sich diese Überlegungen erst gemacht,
nachdem also objektorientierte Programmiersprachen in die Welt gekommen sind.
Das ist vielmehr eine ganz, ganz lange Tradition. Eigentlich kann man sagen,
ist die Frage nach dem Umgang mit Programmierfehlern, Entwicklungsfehlern,
ist so alt wie das Programmieren selbst,
weil Programmieren immer mit menschlichen Fehlern verbunden gewesen ist,
also Entwicklungsfehlern und sich die Frage des Umgangs damit eben schon sehr früh gestellt hat.
Hier sehen Sie jetzt so klassische, traditionelle Ansätze zur Fehlerbehandlung.
Der erste Ansatz ist nun wirklich das einfachste Mögliche.
Das Programm wird aus der fehlerhaften Methode heraus abgebrochen. Beispiel,
Sie kriegen also einen Nullpointer übergeben an einer Stelle,
wo Sie mehr als einen Nullpointer erwarten und dann sagen Sie,
Exit, ich breche das Programm ab
Haben Sie sofort den Anwender am Telefon und sagen,
der sagt Ihnen dann, das Programm ist gerade abgebrochen.
Es hat sich nicht weiter gemeldet. Möglicherweise kriegen Sie noch so das,
was Sie jeden Tag sehen, wenn Sie programmieren,
vermute ich jedenfalls,
einen Stack-Trace und der liest Ihnen dann was vor,
wo Sie denken, das möchte ich jetzt eigentlich alles gar nicht wissen.
Aber das kann man machen. Das ist einfach. Man steckt halt nicht viel besonders,
besonders viel Arbeit in die Fehlerbehandlung rein, sondern akzeptiert,
dass diese Fehler passieren und dann muss man halt mehr
an der Hotline arbeiten
Zweite Methode, liefert einen Returnwert, der vom Aufrufer als Fehler kommt, interpretiert werden soll.
Die lustigeren unter ihnen, wenn ein Nullpointer übergeben wird,
geben als Retarnwert von mir aus 42 zurück.
Und ansonsten tun sie nichts, dass die 42 möglicherweise,
aber so, wenn das die Berechnung eines Kontostandes sein soll,
auch ein legitimer Funktionswert sein könnte, das ist ja noch lustiger, oder?
Aber ich habe jetzt keine Lust, mich mit,
also ich programmiere, habe in diesem Moment keine Lust,
mich mit einer Null-Pointer-Acception zu beschäftigen, also gebe ich einen Wert zurück,
von dem ich irgendwo im Code auch hinschreibe im Kommentar,
Achtung, wenn ein Null-Pointer übergeben wird,
dann gebe ich 42 zurück.
Das kann zu Folgefehlern führen, die extrem schwer erkennbar sind,
also wo dann nachher die Ursache dafür ist,
eben weil der Klient, der sie aufgerufen hat,
denkt, alles ist gut.
Also man hat halt so, das ist ein Missverständnis,
ist dann da aufgetreten.
Dritte Möglichkeit, eine global lesbare Variable. Das wissen sie
möglicherweise gar nicht,
was das ist
Weil sie kennen ja als so höchste Form der Globalität ja
nur ein Klassenvariablen oder Variablen, die in einer Klasse sichtbar sind.
In traditionellen, also in Programmiersprachen der dritten Generation gibt es die Möglichkeit,
Variablen zu deklarieren, die für alle Beteiligten,
so Klassen von mir aus, so sichtbar sind.
Und dann mag es auch eine Variable geben, die heißt also Error.
Und die kriegt dann also in dem Moment, wo man
einen Fehler feststellt, kriegt ihr den Wert minus eins.
Und dann kann man nur hoffen, dass jemand,
der sie aufruft, nach dem Aufruf schaut,
ob also in dieser Error-Variable irgendein Wert drinsteht,
der da nicht drinstehen sollte
Das kann man hoffen. Und dann hofft man das.
Und dann programmiert man halt weiter. Man hat ja seine Pflicht getan.
Die letzte Methode ist schon etwas aufwendiger, sogenannte Call-Back-Operation.
Das ist ein Mechanismus, mit dem wir uns hier noch nicht weiter beschäftigt haben.
Ich als Aufrufe übergebe eine aufgerufenen Operation, eine Methode,
ein Objekt, für den Fall, dass bei der Verarbeitung,
der von mir aufgerufenen Methode etwas schief läuft,
dann möge ich bitte mit dieser speziellen Operation,
die ich übergeben habe, zurückgerufen werden.
Das kann man machen. So, wenn man das tut,
jetzt kommen wir mal zur Diskussion dieser vier Mechanismen, dann hat das jeweils unterschiedliche Konsequenzen.
Ich habe über die anderen schon gesprochen,
die Konsequenzen bei den anderen drei Arten von Fehlerbehandlungen,
traditionellen Arten von Fehlerbehandlungen, was die Callbacks tun,
geht also prinzipiell in die richtige Richtung,
nämlich einem aufgerufenen Dienstleister wird die Möglichkeit gegeben,
eine spezielle Operation zu rufen in dem Moment,
in dem er feststellt, hier ist etwas eine Situation eingetreten,
die nicht sein soll.
Und deswegen rufe ich jetzt eine spezielle Operation auf,
die dazu führt, dass der Aufrufer eine Sonderbehandlung, eine Ausnahmebehandlung durchführt.
Wenn man das aber mit diesem Ihnen jetzt bekannten normalen Programmiersprachlichen Mitteln tut,
dann führt das also zu einem, irgendwo steht was von Blähungen.
Das mag man ja auch nicht. Also das bläht die Schnittstelle,
die normale Schnittstelle eines einer Klasse,
auch wie die normale öffentlich sichtbare Operationsschnittstelle einer Klasse auf,
hat also ein F, also diese Art des Umgangs mit Fehlern hat also einen Effekt,
der auch nicht ganz Seiteneffekt frei ist.
Deswegen, deswegen gibt es eben,
weil das mit den Fehlern so unangenehm zu behandeln ist und man trotzdem einen ein eingängigen Mechanismus haben möchte,
gibt es dieses Sprachkonzept der Ausnahmen, der Ausnahmebebehandlung gesehen dann,
1, 2, 3 Programmiersprachen, explizit genannt,
die so wegweisend gewesen sind, um so das Konzept,
das dann nachher auch im Java implementiert worden ist,
um das konzeptionell aufzubereiten.
Die erste Sprache Clou werden sie wahrscheinlich nie in ihrem Leben aktiv drin programmieren.
Clou steht für Cluster. Cluster sind sowas ähnliches wie Klassen
. Das war so eine Experimentalsprache in den 70er Jahren,
ist die am MIT entwickelt worden.
Die hat als erste Sprache konzeptionell der was als erster Programmiersprache möglich,
konzeptionell direkt über Ausnahmebehandlungen, also das auch auszudrücken im Programm.
Die Sprache Ada ist so, gibt es auch nur noch
eine geringe Chance, dass sie die mal sehen werden.
Es sei denn, sie arbeiten für so Organisationen wie das
amerikanische Verteidigungsministerium unmittelbar oder mittelbar. Das ist die Sprache,
die zur Vereinheitlichung, gerade wie soll ich das ausdrücken?
Militärische Applikationen erfunden worden ist, geschaffen worden ist.
Die beinhaltet auch ein Konzept Ausnahmebehandlung mittlerweile, also so weltweit,
wenn man mal so schaut, wie viel Coden wird,
in welchen Programmiersprachen implementiert.
A, da ist unter 1 Prozent, ist das mittlerweile Eifel.
Die Sprache haben Sie auch schon mal hier gesehen,
als wir über das Vertragsmodell gesprochen haben.
Diese Sprache hat auch ein eigenes Konzept zum Umgang mit Ausnahmen.
So, alle diese Sprachen inklusive Java verfolgen,
also folgende Ziele, mit der Einführung eines eigenen Exception Mechanism
eines eigenen Ausnahmebehandlungsmechanismus.
Fehler sollen nicht
einfach ignoriert werden
Will ein eigenes, explizites Sprachmittel haben,
um mit Fehlern umgehen zu können. Der Normalfall,
das war ja bei diesem Callback-Mechanismus, war das ja das Problem.
Der Normalfall soll, also weiterhin einfach zu programmieren sein und,
also nicht die Schnittstelle aufblähen. Und das letzte Ziel,
das jetzt insbesondere auch mit objektorientierter Programmierung, sprich Vererbung,
möglich ist, wir möchten unterschiedliche Typen von Fehlern,
möchten wir unterscheiden können und einen Mechanismus,
um diese Typen von Fehlern unterscheiden zu können,
ist die Vererbung,
ist der Einsatz der Vererbungsbeziehung
Was sind jetzt, wie ist jetzt das Exception-Konzept in Java umgesetzt?
Das ist die beruhigende Nachricht, es gibt überhaupt nur beruhigende Nachrichten hier.
Es gibt keine beunruhigenden Nachrichten. Aber ganz besonders beruhigend dürfte
für sie sein Exemp, das Exceptions in Java-Objekte sind.
Also das, was sie schon kennen, noch nichts anderes.
So was sind Objekte, Objekte sind Exemplare von Klassen.
Also gibt es wohl, das ist der naheliegende Schluss,
gibt es auch sowas wie Acception-Klassen.
Aus dieser Aussage Exceptions
sind Klassen
Folgt auch das, was ich vorhin, also ist,
der Zusammenhang zu dem, was ich vorhin gesagt habe,
unterschiedliche Typen von Exceptions sind möglich, durch den Einsatz der Vererbungsbeziehung.
Das ist eben, weil jede Klasse auch ein Typ definiert,
ist dieser Kurzschluss, das ist so negativ,
ist das auch ein Zwangs,
ein zwanghafter Schluss an der Stelle.
Also wir können in Java eigene Exceptions uns schaffen und mit
diesen Exceptions können wir dann Ausnahmebehandlungen vornehmen
Wie sieht das dann aus? Auch diese Vorlesung geht nicht zu Ende,
ohne dass sie ein paar neue Schlüsselwörter zur Realisierung dieses Konzeptes kennenlernen.
Wenn sie eine Acception auslösen wollen,
dann tun sie das und wir zeigen ihnen Fred auch,
wird ihnen gleich noch, also ganz hautnah Code zeigen,
dann lösen sie das durch Verwenden des Schlüsselboards Throw auf.
Also sie werfen eine Ausnahme, sie lösen eine Aus,
sie lösen eine Acception aus,
indem sie sie werfen
Wenn Sie etwas werfen wollen, dann muss dieses Geworfene vorher deklariert werden. Das heißt,
an der Stelle, wo eine Ausnahme ausgelöst werden soll,
werden Sie irgendwo das Schild, nicht irgendwo,
sondern an einer bestimmten Stelle, werden Sie das Schlüsselwort Throws verwenden.
Dann sieht es jeder, der also auf diesen Coach schaut,
weiß Bescheid, aha, da könnte mal eine Ausnahme ausgelöst werden.
Und das ist durch dieses Schlüsselwort Throws beschrieben. So,
die letzten drei oder die nächsten drei, die letzten drei Schlüsselworte
Die sind für den Umgang mit einem ausgelösten Fehler, sind die reserviert.
Die Situation, die Sie sich vorstellen, ist so,
und ich schaue auf diesen Code des Dienstleisters,
den ich da aufrufen möchte, und der sagt also,
ich löse möglicherweise mal eine Ausnahme aus.
Dann wissen Sie, der Compiler wird mich jetzt dazu verpflichten,
das zur Kenntnis zu nehmen. Und dieses zur Erkenntnissen nehmen,
bedeutet, ich muss den ganzen Code,
den ich jetzt aufrufe, der immer damit droht,
eine Ausnahme auszulösen,
den werde ich in einen sogenannten Try-Catch-Block bekommen
Werde ich den ummanteln. So nach dem Motto,
jetzt fängt also der Try-Block an, also die Folge von Anweisungen,
die ich aufrufe, die möglicherweise eine Ausnahme auslösen.
Und jetzt rufe ich die erste auf, die zweite und
dann möglicherweise jetzt beim Aufruf dieser Operation passiert tatsächlich.
Es wird die Ausnahme ausgelöst. Und dann wird der Code ausgeführt,
der in dem Catch-Block steht, so nach dem Motto,
ich habe es versucht, es ist schief gelaufen,
aber ich bin darauf vorbereitet,
jetzt kann der Programmablauf in dem Catch-Block weiterlaufen
So nach dem Motto, ich habe die aus, das,
was da an der anderen Stelle verzeihen sie, das Denglish-Journalish,
das, was in der einen Stelle gethroat wird,
wird an der anderen Stelle gecashed.
So, der Aufgerufene sagt, ich löse die Ausnahme aus.
Ich werfe eine Ausnahmebehandlung an und an der Stelle,
wo man an den Aufruf vorgenommen hat,
wird diese Ausnahmebehandlung jetzt aufgefangen in einem Catchblock,
wird jetzt versucht zu retten, was noch zu retten ist.
Und am Ende der Geschichte finally,
was das im Detail bedeutet,
wird man
sich noch anschauen
Finany wird noch etwas Code ausgeführt, der immer ausgeführt wird.
Egal was vorher passiert wird, dafür ist dieses,
der Name sagt es ja bereits,
final wird also noch ein Stück Code ausgeführt,
das innerhalb, das so hinter diesem Schlüsselwort steht.
Meinetwegen, man schreibt auf dem Bildschirm Dute und Unexpected Error,
all your files very moved.
Finally. Ja, yours.
Ja, bitte
Nichtheit macht, weil er ein Grat in die feuere Herrschaft ist.
Fred, hast du die Frage verstanden? Naja,
wenn der Exception geboren wird, für die eigenen Stromkasten,
dann lasse ich euch nicht vorwerfen. Ich würde eventuell kostenlos
von uns. Einen Moment. Was Sie jetzt gerade erleben,
ist ein wunderbares Beispiel für die Unzulänglichkeit menschlicher Kommunikation.
Ich habe Fred gefragt, hast du die Frage verstanden?
Diese Frage hat Zwei Antwortmöglichkeiten. Sagen wir drei. Ja
, nein. Vielleicht, was war? Dann werden es
sogar vier. Meine Absicht ist, dass du die Frage,
wenn du sie jetzt mit Ja beantwortest, dann sage ich, mach mal später.
Ich kann es erklären. So, dann... Ja. Ja,
das ist, wenn, also Leute sie fragen,
also warum das mit der Softwareentwicklung so kompliziert ist,
fragen sie einfach zurück.
Können Sie mir sagen, wie spät es ist?
Und wenn die dann sagen, 14.30 Uhr,
sagen Sie, das ist das Problem der Softwareentwicklung.
Das ist genau das ist es
Nicht genau, aber das ist eins der zentralen Probleme der Softwareentwicklung.
Also wir kommen auf Sie zurück mit Ihrer Frage. Grundsätzliches. So,
hier steht jetzt, viel von dem habe ich schon erzählt,
wenn Sie Code aufrufen, der eine Ausnahme auslöst und Sie,
der Aufrufe, wahlweise nicht diese Ausnahme behandeln wollen oder behandeln können,
dann wird diese Ausnahme weitergereicht.
An denjenigen, der sie aufgerufen hat. Und es gibt immer
ein definiertes Ende dieser Kette. Das ist die Operation Man.
So, an der Stelle hört die Verarbeitung immer auf.
Und die behandelt diese Ausnahme. Und die hat eine Standardart,
um mit der Ausnahme umzugehen. Und die heißt Ende.
Wir machen jetzt nichts mehr. Und dann haben sie genau
das Problem, dass sie eigentlich nicht genau das,
aber dann haben sie
ein Problem
Was sie vermeiden wollten, haben sie sich dann eingefangen,
durch diese nicht gefangene Ausnahme,
nämlich ihr Programm ist einfach abgebrochen und der Anwender des Programms
steht da und hat einen Stack Trace vor sich.
Und das ist also in der Regel nicht das,
was ihr Anwender erwartet. So, da sehen Sie es
auch. Axel hat das sehr hübsch, metaphorisch formuliert,
wird eine Ausnahme überhaupt nicht abgefangen,
so bahnt sie sich ihren Weg bis zum Aufruf der Main-Methode.
Und dann bricht der Damm
Okay, das heißt also, wenn sie nichts tun,
dann bricht ihr Programm einfach ab.
Und das ist so für die Programme, die sie schreiben,
ist das jetzt so, das sind ja keine Programme,
die im Produktivbetrieb eingesetzt werden, ist das also möglicherweise noch vertretbar.
Alles, was jemals echte Benutzer sieht,
für die ist das ein Licht, eine nicht vertretbare Herangehensweise.
So, Sie sehen jetzt,
also wie wir nochmal in der schriftlichen Form,
wie eine Acception ausgelöst werden kann und unter welchen Randbedingungen
eine Acception ausgelöst werden kann
Gut, die werden jetzt noch eine Unterscheidung einführen hier.
Das ist die Unterscheidung zwischen Geprüften und Ungeprüften Exceptions.
Das betrifft insbesondere so die Unterscheidung, auf die ich am Anfang
eingegangen bin zwischen Entwicklungs- und Umgebungsfehlern. Weil je nachdem,
um welche Art von Fehler es sich handelt,
geht man davon aus, dass eine Sonderbehandlung,
also von Ihnen, also besondere bei Entwicklungsfehlern,
dass also geprüfte Exceptions verwendet werden sollen,
weil das Fehler sind,
die im Normalfall nicht passieren sollten.
Bei den Umgebungsfehlern
werden ungeprüfte Exceptions eingesetzt
Weil das Fehler sind, die sie überhaupt nicht unter Kontrolle haben,
da brauchen sie auch nicht weiter was zu kontrollieren.
Es ist so nach dem Motto, ich kann gar nicht
unterscheiden, also was eigentlich alles schiefgehen kann.
Also werde ich da mich auch nicht explizit drum kümmern müssen.
Hier sehen Sie jetzt so Beispiele für geprüfte und ungeprüfte Exceptions.
So fangen wir mal mit den Geprüften an. So eine Timeout Exception,
also bei der Verbindung zum, wenn da etwas schiefläuft,
bei der Verbindung zum Internet oder zu einem entfernten Server,
dann ist es etwas, wovon sie ausgehen können, Dass das mal passiert,
weil schließlich sind sie derjenige, der diese Verbindung versucht aufzubauen.
Und dann, wenn das nicht klappt, dann sollten sie
aktiv darauf reagieren können und nicht einfach das Programm abbrechen.
Dann sollten sie halt sowas ausgeben wie eine Fehlermeldung,
eine Verbindung zu einem entfernten Gerät ist nicht möglich.
Während die Ungeprüften Exceptions, also die hier genannt sind,
also sollten, das sollte im Normalfall nicht passieren. Also,
dass sie Array Index out of bounds Exceptions produzieren,
dass sie einen Array versuchen, mit dem Index minus 1 zu sprechen,
das sollte im Normalfall nicht passieren und deswegen brauchen sie da auch keine explizite Ausnahmebehandlung für zu schreiben.
Das sind jetzt vermutlich jedenfalls vergleichsweise viele Unterscheidungen und Begrifflichkeiten,
mit denen ich jetzt hier hantiere, die für sie neu sind.
Wir versuchen diese Art von Situation für sie dadurch zu entschärfen,
dass wir so ihnen, das werden wir im Laufe des Semesters noch an verschiedenen Stellen so handhaben,
dass wir in so ein paar Regeln an die Hand geben und die einfache Regeln,
die so für den Holz, heute für den Umgang mit Exceptions,
die sie bitte beherzigen sollen.
Also zunächst mal dann auch in ihren Übungen. So,
die geht so, wenn eine Methode A eine andere Methode B benutzt,
die eine geprüfte Exception deklariert, Achtung,
dann müssen in der Methode A-Vorkehrungen für den Fall getroffen werden,
dass die deklarierte Exception wirklich auftritt.
Ja, das ist hoffentlich nachvollziehbar. Also wenn schon jemand sagt,
also es kann sein, dass ich eine Exception werfe,
dann sind sie als derjenige, der diese Methode benutzt,
in der Verantwortung da auch darauf zu reagieren,
falls dieser Fall tatsächlich eintritt
So, vielleicht jetzt noch ein bisschen hups, oder?
Noch ein bisschen Code, so in der Übersicht. Wenn Sie solchen Code der Aufruf aufrufen,
der möglicherweise eine Ausnahme auslöst,
habt ihr das schon so mündlich gesagt, dann wird,
wenn Sie häufig, also das sind so Muster,
die sich so in Ihrer Wahrnehmung einbrennend werden,
dann werden Sie solche Trial Catch Finany Blöcke entdecken,
also zwischen Try und Catch steht genau der Block,
den Sie jetzt versuchen aufzurufen,
wenn innerhalb dieses Blocks
etwas passiert
Was außerhalb des normalen Programmflusses ist, dann wird der Catchblock aktiviert.
Und sie werden auf verschiedene Möglichkeiten kennenlernen,
diese so auch unterschiedliche Catchblöcke zu definieren, je nachdem,
welche Art von Fehler, davon hat sich ja auch am Anfang gesprochen,
welche Art von Fehler eigentlich auftritt.
Weil so wie ich ganz am Anfang gesagt habe,
Exceptions sind Objekte, wir sehen hier diesen Bezeichner E,
der ist von einem bestimmten Typ. Und jetzt,
wenn das so ist und sie verschiedene Catchblöcke angeben können für das,
was da möglicherweise schiefläuft bei dem, was sie aufrufen,
dann resultiert daraus auch die Frage, in welcher Reihenfolge werden.
Oder gibt es eine Reihenfolge, in der die aufgerufen wird?
Und darauf gibt es dann, also weil bei uns,
das ist möglichst etterministisch, gibt es immer auch eine Antwort,
ja, in der Reihenfolge, in der also ein passender Gadgeblock gefunden wird.
Es wird immer der Erste ausgeführt und jetzt können wir anfangen zu überlegen,
wenn das so unterschiedliche Typen sind von Exceptions,
die da gefangen werden können, kann man sich als Programmierer auch überlegen,
dass die Reihenfolge, in der ich die da hinschreibe,
auch eine Auswirkung hat für die Laufzeit des Programms,
bezüglich der Frage, welcher wird denn da jetzt eigentlich ausgeführt?
Da ist sehr viel, da gibt es sehr viel Spielraum für Entscheidungen.
Ich glaube, diese Folie habe ich schon mal gezeigt,
als ich über Vererbung, über die Motivation von Vererbung gesprochen habe.
Hier sehen Sie jetzt, die stellen insbesondere,
in die sie sich einhängen können, wenn sie unterschiedliche Arten von Exceptions,
den normalen, in Anführungsstrichen, den normalen Exceptions,
die in den Java-Bibliotheken vorhanden sind, noch hinzuzufügen wollt.
Das heißt also, mit diesen Exception-Mechanismus haben Sie jetzt die Möglichkeit,
für Sie sich in ihrem Programm ganz explizit eigene Arten von Ausnahmebehandlung zu definieren.
Und das ist etwas, was sie in ihrem Leben als Arbeitsleben,
als Programmierer vermutlich auch an verschiedenen Stellen tun werden,
weil sie wollen, sie wollen,
falls etwas schief läuft in den Programmen, die sie schreiben,
wollen sie eine möglichst umfassende Information darüber haben,
was da passiert ist, um diesen Fehlerfall erstens um diesen Fehlerfall sehr aufgetreten ist,
um den zu beheben.
Das Programm, gegebenenfalls gesittet, zu beenden. Und zweitens,
um also gerade diese Entwicklungsfehler, auf die sie ja dann gestoßen sind,
um die, also in einer nächsten Programmversion zu beheben.
Bei den Umgebungsfehlern muss man halt mal schauen, welche Art von Umgebungsfehler das ist.
Aber wenn ihr Programm sich als wenig robust für den Einsatz in seiner Umgebung zeigt,
dann ist das ja auch etwas,
was so durch die geeigneten Exception-Händler gezeigt werden kann.
Und sie können dann Maßnahmen außerhalb des Programms treffen,
um diese Art von Umgebungsfehler
zu minimieren
Geht das? Also wenn man eigene Exceptions schreiben möchte,
sieht aus, wie der normale Einsatz der Vererbungsbeziehung und ist es auch.
Das ist also nichts anderes als eine eigene Klasse schreiben und
diese Klasse dann zum Auslösen von eigenen Exception-Objekten zu verwenden.
So, zum Abschluss dieses Teils,
wozu werden also Exceptions eingesetzt, im Wesentlichen als Abstraktionshilfe?
Sie sehen das hier. Das ist gerade so das,
was da steht mit den Enticipated Exceptions and their handlers
Also wie man das verstehen kann. Also hier wird gesagt,
so die Metaphorik, die hier verwendet wird, ist,
das sind so Fußnoten. So, mal bitte,
wie man halt Fußnoten in längeren Texten einsetzt,
unter anderem um zu sagen,
dass diese Aussage unter besonderer Berücksichtigung von getroffen wird,
genau so versteht man, also kann man da nicht genauso,
aber das sage ich jetzt schon mal schon wieder.
Aber das ist so ein nachvollziehbares Verständnis von Ausnahmebehandlungen in Programmen,
das Programm selbst beschreibt den normalen Fluss der Dinge.
Und die Exceptions beschreiben an welchen Stellen der Entwickler Annahmen darüber gemacht hat,
in seinem Kontext eigentlich, oder was bei der Programmausführung schiefgehen kann und benutzt es dann als Mittel,
um genau solche Ausnahmesituationen auch ausdrücken zu können.
So, das ist so die erste, nicht zeitlich,
bin ich schon fast durch,
habe ich jetzt etwas mehr Zeit als die Hälfte meiner Hälfte der Vorlesung für verwendet,
aber das ist es mir auch wert, weil so Ausnahmebehandlung etwas ist,
Also man beschäftigt sich ja nicht gerne damit,
dass so etwas schiefgehen kann während der,
also während man Programme entwickelt.
Man ist ja gerne auf dem sogenannten Happy Path.
Also wenn alles gut ist, dann machen wir das.
Aber leider Gottes sind, also die Probleme treten halt in dem Moment auf,
wo etwas nicht auf dem Happy Path ist. Und dann muss man,
also gerade, wenn man sich damit beschäftigt,
sicherheitskritische Applikationen zu beschreiben, so muss man mitunter,
so nach dieser 80-20-Regel,
man muss sich halt 80 Prozent der Zeit mit den
20 Prozent der Probleme beschäftigen,
die halt wirklich Ärger ärgern
Bereiten. So, zweiter Teil. Und jetzt beschäftigen wir
uns mit einem uralten Konzept der Softwaretechnik, nämlich Modularisierung.
Und das, was ich Ihnen, die Folie,
werden Sie nicht im Internet finden, im Kommen Sie.
So ein Artikel, den ich Ihnen für eine müßige Abendstunde
empfehlen möchte, finden Sie auch im Internet.
Real Programmers,
Don't use Pascal
Das ist so ein Artikel, der ist,
glaube ich, irgendwas in den 70er Jahren geschrieben worden.
Da wird das hohe Lied auf Vororthan-Programmierer gesungen. Und Fahrthan-Programmierer,
das sind so Leute, die schicken halt Sonden zum Mars
oder zu Venus und haben 64 Kilobyte Hauptspeicher,
wenn überhaupt, zur Verfügung. Und die erste Aufgabe,
die man als Vortragen-Programmierer in der neuen Firma typischerweise bekommt, ist,
dass man ein 250.000 Zeilen langes Programm um den Faktor 5 beschleunigen soll,
ohne dass man den Prozessor austauscht.
Okay, dann gucken Sie sich die Struktur dieses Programms
an und das sieht ungefähr so aus und das,
was Sie sich jetzt fragen, ist so, Wo fange ich da an?
Dass da könnte doch ein guter Ausgangspunkt sein, oder?
Das sieht anders aus als alle anderen.
Vielleicht gucke ich mir doch lieber mal die anderen an.
Oder vielleicht suche ich mir einen anderen Arbeitgeber. Vielleicht,
oder vielleicht auch einen anderen Job, so einen Gärtner.
Das ist doch auch hübsch. So, jetzt habe ich
diese Geschichte über Vortragen erzählt. Die Geschichte könnte ich auch über
Java erzählen. Sie kommen irgendwo hin und haben zehn Leute,
über drei Jahre was gemacht und dann versucht, sagen sie,
habt ihr mal ein Klassendiagramm, wie die Struktur aussieht,
ja, haben wir, dann zeigen die ihnen das da.
Jetzt sind sie schlauer, aber sie wollten es ja haben.
Das muss nicht sein. Das passiert zwar immer wieder,
aber immer mal das, was unsere Aufgabe hier als Lehrende ist ja,
ihnen zu sagen, so kann man schön große Programme herstellen,
die übersichtlich aussehen, das sieht nachher das Nicht-Tun, ist ja dann ihr Problem.
Unter den Randbedingungen, unter denen sie arbeiten, passiert das halt.
Das, was ich Ihnen hiermit zeigen möchte, ist,
wenn Sie als Sprachmittel in Objektorientierten Programmiersprachen nur das Mittel Klasse haben,
dann kann es darauf hinauslaufen, dass also Ihre Programme auch so aussehen.
Deswegen stellen wir Ihnen noch ein weiteres, ein etwas höheres Konzept vor. Und das ist das Modulkonzept,
das es Ihnen ermöglicht, Klassen selbst noch einmal zu strukturieren,
sprich so ein etwas, so ein, man könnte jetzt,
also als Metaphorik nehmen, einen Behälter zu finden,
in dem Sie Klassen bringen können, sodass sie eine etwas gröber,
granulare Struktur über die von innen geschriebenen Klassen bilden können.
Und das dahinter liegende Konzept ist das Modulkonzept. Einer der
Gründe für die Einführung des Modulkonzeptes war, dass also damals letztes Jahrtausend,
so bei den Don dort zur Verfügenden stehenden Rechnen,
die sogenannte Mean-Time Between Failure, also häufig noch im Sekundenbereich gemessen werden musste.
Mean-Time Between Failure beschreibt,
Ich werfe den Compiler an und wenn die Übersetzung des Stücks Programms,
das ich habe, sagen wir mal 20 Sekunden dauert,
die Meantime Between Failure, aber nur 10 bis 15 Sekunden war,
dann habe ich eine gute Chance,
dass dieses Stück Programm niemals übersetzt wird.
Eben weil der Computer vorher zusammenbricht. Was macht man denn
in so einer Situation? Man macht die Programme kleiner.
Man schafft Übersetzungseinheiten, die zu einem späteren Zeitpunkt dann zu
einem lauffähigen Programm zusammengebunden werden sollen.
Und diese Übersetzungseinheit, die nenne ich jetzt mal Modul
So, also habe ich jetzt statt einmal 20 Sekunden,
habe ich vielleicht, also vier Programmeinheiten,
die sich jeweils in fünf Sekunden übersetzen lassen.
Und ich bin schon ein gutes Stück unterhalb meiner Meantime Between Failure.
Das ist doch eine super Idee. Also kann ich das alles übersetzen,
nachher zusammenbitten, und es läuft bestimmt so 15 Sekunden lang,
bis das Ding dann bei der Ausführung zusammenbricht.
Aber das ist ein anderes Thema. So, das Modulkonzept,
also ein Grund für die Einführung, waren so technische Randbedingungen.
Ein anderer Grund, und das ist so das eigentliche Motiv,
über das wir heute sprechen,
weil die Meantime Between Failure ist ja dann heutzutage dann doch
etwas länger geworden,
Gott sei Dank
Beziehungsweise den Ingenieuren, sei Dank. Wir wollen einen Organisationskonzept haben,
mit dem wir Klassen in Gruppen zusammenfassen können,
sodass wir wiederum als Einheit darüber sprechen können.
Und das ist ein weiterer Effekt der Einführung dieses klassischen Modulkonzepts.
Nun, ein Modul ist dadurch gekennzeichnet, dass es eine Exportschnittstelle hat.
Und an dieser Exportschnittstelle im traditionellen Verständnis gibt es Operationen, Typen und Konstanten.
Das ist das, was nach außen hin sichtbar ist.
Was innerhalb dieses Moduls ist, alle Variablen,
haben wir schon drüber gesprochen, lokale Prozeduren,
lokale Typen, also alles das, was es braucht,
um die Exportschnittstelle zu implementieren.
Wo ist eine Exportschnittstelle? Tja, meine Zeit ist um
. Da gibt es noch eine Importfische, diese Importfische,
natürlich, weil drehe ich mal so ein bisschen auf,
dreht fünf Minuten Bräu nach.
Wo eine Exportschnittstelle ist, da ist eine Importschnittstelle nicht weit
Diese Import-Schnittstelle gibt an, das Pendant, das Kompliment,
wenn ich diese Export-Schnittstelle realisieren möchte,
dann brauche ich von anderen Modulen genau diese Operationen,
diese Typen und möglicherweise noch diese Konstante.
Und dann habe ich so ein Ordnungsprinzip,
so stellen Sie sich jetzt erstmal das so vor,
dass innerhalb eines Moduls gibt es Klassen,
also Typen, und die sagen jetzt,
also ich gehöre zu diesem Modul und stehe insgesamt
Stehe ich für eine bestimmte Art von Funktionalität,
die durch verschiedene Klassen intern realisiert ist.
Und das ist so die Interpretation des Modulprinzips mit einer objektorientierten Programmiersprache.
Jetzt hat es aber dieses Konzept des Moduls,
gibt es in dieser Form nicht in Java.
Und ein Argument dafür ist,
dass eine Java-Klasse selbst schon ziemlich viele Merkmale eines Moduls trägt,
insbesondere auch die Fähigkeit,
dass sie
Klassen ineinander schachteln können
So ein Teil von Folien, die ich hier ausgeblendet habe.
Also das gibt schon Ähnlichkeiten, zwischen dem Klassenkonzept und dem
klassischen Modulkonzept. Es gibt aber darüber hinausgehend,
gibt es in Java noch ein Strukturierungsmittel mit dem,
und das ist das, womit ich jetzt dann heute schließen werde.
Ein Strukturierungsmittel in Java, mit dem sie Klassen zu Gruppen,
die Pakete genannt werden, zusammenfassen können. Pakete, English,
Packages, kommen also einem anderen Aspekt des Modulkonzepts ziemlich realisieren
einen anderen Aspekt des Modelkonzeptes, nämlich, dass sie einen Sichtbarkeitsraum schaffen.
Sichtbarkeitsraum kennen sie bereits aus dem Klassenkonzept. Alles,
was sie als Public deklarieren in einer Klasse, ist nach außen hin sichtbar.
Und jetzt gibt es also dieses Package-Konzept, das liegt oberhalb,
also konzeptionell oberhalb des Klassenkonzeptes. Klassen können in,
oder jede einzelne Java-Klasse ist Teil eines Paketes,
wenn man das nicht angibt, ist es ein Standardpaket.
Ansonsten sind sie frei darin zu entscheiden, ich möchte die Klassen,
die ich schreibe, als Teil eines bestimmten Paketes,
sagen wir es von mir, definierten Paketes schreiben.
Und dann können sie auch entscheiden, welche Sichtbarkeit diese Klassen außerhalb des Paketes haben sollen.
Und das ist jetzt so die Idee, wie man das Modulkonzept,
wie man das Modulkonzept in Java realisieren kann beziehungsweise umgekehrt,
wie man das Paket,
wie man das Package-Konzept mit den Mitteln des Modelkonzeptes verstehen kann.
Ich gehe jetzt mal gleich zur letzten Folie
Über Ypsalam, vorletzte Folie. Jetzt haben wir in der letzten Vorlesung,
vorletzten Vorlesung, als wir über Vererbung gesprochen haben,
haben wir schon so die dritte Art von Modifikator hier eingeführt,
also neben Public und Private, die für die Klientenschnittstelle wichtig waren,
haben wir noch den Modifikator Protected eingeführt,
der eine besondere Rolle für bezüglich der Sichtbarkeit in der Vererbungsbeziehung hat.
Und hier sehen Sie jetzt, und damit möchte ich,
das ist also die letzte beruhigende Nachricht,
die ich für Sie habe, wenn Sie das da Modifikatoren für Packages,
wenn sie das jetzt verstanden haben,
was nach meiner Ansicht keine besondere intellektuelle Hürde war,
dann war es das.
Wer gibt es in Jama nicht? Es kommt nichts mehr.
Das war es jetzt. Keine weitere Überraschung mehr. Also,
nehmen Sie das als zusätzliche Motivation zu verstehen, was bedeutet es,
mit Private, Protected und Public im Zusammenhang von Packages sich zu beschäftigen.
Und dann haben Sie sämtliche Sichtbarkeitsregeln, die man in
dieser Sprache verwenden kann, begriffen.
Ich wünsche Ihnen einen frohen Tanz in den Mai
Nicht mit Steinen schmeißen. Und wir sehen uns
nächste Woche wieder. Schön. So. Okay. Ja,
ich hatte so eine kleine Diskussion intern.
Wie lange kann ich das Thema Stacks eigentlich noch ausschlachten?
Ich glaube, das kann ich das ganze Semester noch weitermachen.
Aber ich dachte so als kleine Erholungspause machen wir mal was anderes zwischendurch.
Irgendwas, was vielleicht nicht ganz so abstrakt ist.
Also ich habe ja ein Projekt gestern geschrieben,
das nennt sich Animal Farm.
Das starte ich einfach mal so
Und dann hat man ja auch unsere Konsole.
Wir wissen ja noch nicht, wie man grafische Oberflächen programmiert,
hat man hier so eine schöne Konsole.
Aber ich mache einfach mal Vollbild, dann muss ich hier
nicht so viel. So, ja, okay.
Enter the Names of Animals, Laket, Cow Orlama.
Aha. Dann mache ich das doch mal.
Cat, was passiert da? Ah ja. Für Domestic
Cat ist das Maul usually furry domesticated and conniverous memor.
Okay, könnt ihr euch vielleicht vorstellen, was passiert,
wenn ich Kao eingebe? Es kommt eine ähnliche Beschreibung,
wenn ich Lama eingebe, kommt es. Eine andere Beschreibung.
Die werden also wohl irgendwo in den Anden als Packesel verwendet.
Ja, und wenn ich irgendwas anderes eingebe,
Da hat er keine Ahnung, was das sein könnte.
Kennt also nur diese drei Tiere und kann mir sagen,
worum es nicht doppelt handelt. Das klingt ja irgendwie
so ganz nett, aber auch nicht so wahnsinnig hilfreich.
Beenden wir das Programm einmal. Und schauen uns mal an,
wie es gebaut ist. Main und Rappel zeige ich euch jetzt nicht mehr,
das kennt ihr ja schon aus den ganzen Stack-Dingern.
Wir gucken uns jetzt nur diesen Animal-Service an.
Gut, ein Service. Was macht denn dieser Service so?
Also intern hat dieser Service eine Map. Maps kennt ihr,
glaube ich, auch aus SE1, vielleicht nochmal als kleine Wiederholung
Eine Map ist so ähnlich wie ein Set,
also es können keine Duplikate auftreten. Ich tue aber jetzt
nicht einfach nur ein Element in diese Map rein,
sondern ich verknüpfe mit diesem Element ein anderes Element.
Man nennt das gerne Schlüsselelement und das nennt man dann wie Wertelement oder so.
Also ich kann anhand eines Schlüssels irgendwelche interessanten Daten ablegen.
In diesem Beispiel ist es so,
zu dem Schlüssel Katze lege ich die Beschreibung zu der Katze
ab und zu dem Schlüssel Kuh lege ich die Beschreibung zu der Kuh
ab und zu dem Schlüssel Lama lege ich die Beschreibung des Lamas ab.
Das ist doch verständlich, oder? Das ist wie so
ein Wörterbuch quasi. Okay. Das ist also die Map. Ja,
und da kommt ja nur diese eine Operation,
wo ich also ein Tier übergebe oder reinstecke und hoffentlich eine sinnvolle Beschreibung zurückbekomme,
was das denn für ein Tier ist.
Wie funktioniert das
Ich frage also diese Map, hey,
schau doch mal nach, ob du einen Schlüssel hast,
dieses Animal und liefer mir bitte die Beschreibung dazu zurück.
Jetzt kann das aber passieren, wenn ich zum Beispiel Dog
eingebe, dass es gar keine Beschreibung dazu gibt.
Und dann kommt ein Nightpointer zurück. Nur das fange ich dann einfach ab.
Und die Beschreibung zu unbekannten Tieren ist immer dieselbe, sorry,
never heard of dog oder elephant oder was auch immer.
Ja. Das ist so die ganze Struktur, die dahinter steckt.
Der Rest ist nur Eingabe und das ist nicht spannend,
das kennt ihr ja schon.
Gibt es zu dieser Map irgendwelche Fragen? Eine Map,
die zu einem Tier, einer Beschreibung des Tiers irgendwie anbietet
und es ist immer dieselbe Map mit drei Tieren.
Ist trivial, oder
Gut. Dann schließe ich das jetzt einmal,
verberge das mal und will jetzt einmal gucken,
dass ich einmal die Lösung quasi,
zu der wir heute hinarbeiten wollen.
Oh. Ja, nee, das ist richtig.
Dass ich euch die einmal zur Laufzeit präsentiere, was unser Ziel ist.
Ich hoffe, das funktioniert so. Okay, wir sind wieder
hier unten. Jetzt gebe ich mal ein anderes Tier ein.
Also oder so, ich kann ja mal eine Challenge machen.
Ihr wisst ja jetzt ja nicht, wie viele Tiere ich
da eingebaut habe. Also fünf Leute dürfen sich melden und
mir einen Tiervorschlag auf Englisch sagen und dann gucken wir mal,
ob das
da drin ist
Hm? Wolf? So? Oh. Hm. Was
ist denn jetzt los? Das hatte ich noch nie.
Unreserve Compilation Problems. Okay, ich glaube, es liegt daran,
dass Eclipse nicht gemerkt hat, dass ich das hier aktualisiert habe.
Schauen wir mal ganz kurz, ob er das jetzt verstanden hat.
Ja, ich glaube, jetzt hat er es verstanden.
Ich starte das Programm einfach nochmal. Ich hoffe,
dass das jetzt ein einmaliger Ausrutscher war, weil ich das
auf der Konsole geupdatet habe und Eclipse das nicht mitbekommen habe.
Also Wolf war das, ne? Weil er überlegt,
oh, okay, ich habe dran gedacht. Greywolf,
okay, ja, okay, das war der erste Vorschlag.
Gibt es einen zweiten Vorschlag?
Platthypos, okay. So? Ja, das ist natürlich
ein tolles Tier. Das habe ich bestimmt eingebaut. Oh ja.
Habe ich eingebaut. Okay, drei Versuche habe ich noch.
Ja. Honeybe. Honeybedger, das sind zwei Wörter, oder?
Ich weiß gar nicht, ob mein Programm das unterstützt.
Oh ja. Okay, ja. Du. Wie buchstabiert
man das? So. Dass sie nicht denken, genau.
Ist nicht Englisch, nee, dann kennt er das nicht.
Ja, okay, hat jemand noch einen anderen Englischen,
ein anderes englisches Tier?
Man kennt gar nicht so viele englische Tiere, oder?
Ich glaube, die Raffa habe ich
noch eingebaut
Ja, kennt ihr auch. Kleiner Fischer.
Catfish. Kennt ihr auch. Wollen wir Unsinn eingeben?
Weiß nicht, was dann passiert? Okay, no entry
for Unsinn. Hat jemand eine andere, ja?
Achso. Wie magst du noch nicht? Achso. Wie
buchstabiert man das denn? AX? O-L-O. Tee.
Tee und dann L.
Hm. Ist das Jens Smiley? Ich weiß es nicht
. Ich könnte ja auch mal kurz,
soll ich mal irgendwas eingehen, was vielleicht kein Tier ist?
Vielleicht irgendwie Java oder so? Aha. Das scheint also
nicht nur für Tiere zu funktionieren, das ist ja spannend.
Habe ich die ganze Nacht da gesessen unter Begriffe eingegeben?
Oder was habe ich da wohl gemacht? Hat jemand so
eine Idee, was ich wahrscheinlich gemacht habe?
Ja. Ich nehme einfach die erste Zeit aus Wikipedia, richtig.
Sehr gut. Okay, warum habe ich das gemacht?
Klassischer Anwendungsfall für Exceptions ist ja immer,
das Programm will irgendwie aufs Internet zugreifen und was mache ich,
wenn das nicht geht?
Ich könnte jetzt hier mal den Steck,
ich habe ja gar keinen Stecker
Ich könnte mal das WLAN deaktivieren und gucken, was dann passiert.
Das lasse ich jetzt lieber nachher, komme ich nicht mehr rein.
Okay, dann machen wir jetzt mal Folgendes. Jetzt gehe
ich mal zu dem Branch, zu dem Normalen sozusagen.
Okay, jetzt muss der Clips das wieder mitbekommen,
dass das hier sich geändert hat. Ja, ich bin auf
dem Master. Genau, das ist jetzt nicht übersetzbar,
weil wir uns jetzt um diese ganzen Acceptions noch nicht kümmern.
Und ich zahle euch jetzt mal, wie dieser Animal Service jetzt nur aussieht.
Okay. So. Okay, also es gibt immer noch
diese Map, Das ist jetzt so ein bisschen interner.
Also ich habe ja ganz viele Methoden, die müssen wissen,
um welches Tier geht es gerade und um welche Beschreibung geht es gerade.
Ich will das nicht immer durch die Gegend reichen.
Deswegen habe ich das als Exemplarbar ja auch dann gemacht.
Ist aber nur diese eine Entscheidung von mir.
Das ist immer noch die zentrale Datenstruktur, die dahinter steckt.
Nur Menschen. Ihr seht jetzt im Konstrukt, euch steckt gar nichts mehr rein.
Also von vornherein kenne ich erst mal nichts.
Und dann kommt so eine riesige, so eine riesige komplizierte Methode,
aber ich schaue mir vielleicht erst mal an,
wie dieser Zugriff auf Wikipedia geht.
Ich habe eine Methode geschrieben, Consult Wikipedia. Und ich habe
euch mal ein bisschen eingelesen, wie macht man das überhaupt?
Es gibt also diverse APIs, die man verwenden kann.
Und ein ganz netter Trick ist es,
einfach so eine Adresse zu nehmen,
die hier
Und da einfach das Tier dahinter zu kleben.
Ich kopiere mir das jetzt einfach mal und zeige euch,
was passiert, wenn ich das einfach in den Browser eingebe.
Also zum Beispiel so Dog. Das ist quasi die Adresse,
die ich an Wikipedia schicke. Und was schickt mir Wikipedia
dann zurück? Das speichere ich einmal, ich weiß nicht,
wo mit, ich öffne es mal lieber,
dann habe ich es sofort offen.
So, hier haben wir es. Das sind dann,
kann ich das irgendwie größer machen, mit Steuerung im Hausrat?
Geht natürlich nicht. Das kommt davon,
wenn man das mit einem Editor öffnet, den man nicht kennt,
dann kopiere ich das einfach, gehe ins Sub-Brime-Text.
So, scheint
ein bisschen sehr groß
So, ja. Also ihr seht, da ist am Anfang erstmal
ziemlich viel Zeug. Irgendwelche Metadaten, die wir beschreiben,
was ist das überhaupt für ein Tier oder Artikel oder was auch immer.
Dann sind da irgendwelche Bilder drin und so, puh.
Also dieses ganze Zeug in geschweiften Klammern,
das scheint irgendwie erstmal nicht so wichtig zu sein.
Das werde ich irgendwie ignorieren müssen. Ganz schön viel.
Und hier ist eigentlich der erste Satz. Dann sieht man gleich
das nächste Problem. Diese komischen Zeichen will ich auch nicht haben.
Die sollen irgendwie auch weg. Das sorgt, glaube ich,
dafür, dass es irgendwie fett oder kursiv ist.
Und das ist die andere Variante davon. Dann gibt es hier
irgendwelche Referenzen noch irgendwie, die sagen, ich zitiere Jonah sowieso.
Dann gibt es hier irgendwelche Links. Das musste ich
also alles entfernen. Ich war super beschäftigt gestern
Und ich will euch da nur mal das auf der
obersten Ebene quasi zeigen, was ich da gemacht habe.
Wir gucken uns gar nicht die Implementation an, das ist
furchtbar hässlich. Aber einfach, dass euch klar ist,
in welchen Schritten jetzt dieser Text verarbeitet wird.
Also ich frage erst mal, Wikipedia,
gib mir doch mal diesen rohen Text mit den ganzen furchtbaren Symbolen,
die wir gerade gesehen haben.
Okay, dann könnte es noch passieren, dass man weitergeleitet wird.
Also wenn ihr zum Beispiel Kao eingebt,
dann wird man zu Kettle weitergeleitet.
Das wird hier also auch in meinem Programm behandelt.
Hier entferne ich diese ganzen blöden Metadaten, die in geschweiften Klammern sind.
Hier entferne ich diese mehrfachen Hochkommentar. Hier werden die ganzen
Links entfernt, wo ich zu anderen Artikeln komme
Dann werden hier irgendwelche Bilder entfernt, die man sonst sehen könnte.
Das macht ja auf der Konsole keinen Sinn.
Und diese komischen Refs, die er eben gesehen hatte,
die in spitzen Klammern, werden auch noch weggeschmissen.
Und dann bleibt ein halbwegs lesbarer Text übrig und dann sage ich,
ich möchte bitte nur den ersten Satz haben dieses Textes.
Ja, was ich jetzt noch nicht besprochen habe,
das hat alles mit dieser Weiterleitung zu tun,
ist jetzt auch nicht so interessant.
Was jetzt wirklich interessant ist, ist, diese Methode,
hier geht es um Acception-Handling, die wollen wir uns mal im Detail angucken.
Wie kann ich mit Wikipedia reden? Nun,
ihr seht, da sind auch ganz viele Zeilen rot,
weil er sagt, Achtung, Achtung,
das ist gefährlich,
was du da machst.
Also ich habe mit diesen, ich habe auch noch nicht
so viel gemacht mit so Internet und Java zusammen.
Ich habe mir das einfach mal aus irgendeinem Tutorial von Oracle genommen und ein bisschen angepasst.
Also wenn ihr einfach mal guckt, Java, Internet-Example oder so,
dann findet ihr recht schnell einen Feldtext, der so ähnlich aussieht.
Gut, man muss sich also erstmal ein URL-Objekt erzeugen und
so ein URL-Objekt wird aus einem String erzeugt.
Hier seht ihr also, dass ich den String einfach zusammenklebe,
ganz normale Java-Stringcon-Kartonationen. Ich nehme also diese URL und am Ende sag
ich Title gleich und dann klebe ich da mein Animal dahinter
. Jetzt gibt es wahrscheinlich ganz viele Sicherheitsexperten,
die jetzt bestimmt sagen, oh Gott, Fred,
nein, Injection Attacks und was weiß ich was,
könnt ihr dann gerne später beheben.
Ich kenne mich damit leider nicht
so gut aus
Okay, das ist aber nur die Adresse erstmal an sich.
Ich habe noch gar keine Verbindung hergestellt. Hier stelle ich zur Verbindung
her. Das ist natürlich auch eine potenziell ziemlich gefährliche Operation,
weil was ist, wenn ich gar keinen Internetzugang habe oder was ist,
wenn es diese Adresse gar nicht gibt oder so?
Das kann also auch schick gehen. Was kann hier eigentlich
schiefgehen? Wollen wir mal gucken? Soll ich mal Eclipse
fragen, was da eigentlich schiefgehen kann?
Java Doc ist ja integriert in den Clips.
Wir gucken einfach mal nach, was uns dieser URL-Konstrukter sagt.
Aha, seht ihr das hier unten? Throws,
Melformed, URL-Acception, if no protocol aspecified or an unknown
protocol as found aus back as null.
Okay, das heißt also,
wenn der Programmierer sich hier vertippt und statt HTTP
vielleicht HTTP schreibt
Oder irgendein ganz obskures Protokoll verwendet, wofür hier irgendwie nichts installiert ist oder so.
Dann gibt es da eine Mallformed YouRL Acception.
Was ich also hinter das Protokoll schreibe, ist völlig egal.
Hier wird nicht geprüft, ob es die Adresse gibt oder so.
Es wird nur geguckt, ist das Protokoll und wahrscheinlich prüft dann
auch dahinter Doppelpunkt Doppelslash, dass den Rest würde er nicht prüfen.
Okay, da könnte ich, also jetzt würde ich als Programmierer sagen,
eigentlich kann diese Acception gar nicht auftreten, wenn diese Acception auftritt,
dann habe ich mich hier irgendwie vertippt.
Das wäre irgendwie ein Programmierfehler. Das hat also nichts mehr
zu tun, ob das Internet funktioniert oder nicht. Okay,
was ist jetzt hier, was kann jetzt hier fliegen,
muss ich mal ein bisschen hochscrollen
Returns throws. Ja, das ist so ein toller Javado-Kommentar, oder?
Throws, IO-Acception, if an IO-Acception a curse. Okay,
also man kann sich wahrscheinlich vorstellen, spätestens dann,
wenn mein WLAN hier nicht funktioniert wird, dass wir irgendwie nicht funktionieren.
Möglicherweise auch wenn Wikipedia gerade down ist, das weiß ich nicht.
Leider ist der Kommentar nicht besonders hilfreich. Okay, was
machen wir als nächstes? Dann so ein bisschen Standard-Java-Kram.
Ich sage also, diese Connection gib mir mal einen Strom,
aus dem ich lesen kann,
dann tue ich den in irgendeinen Stromleser rein und der kommt noch in einen gepufferten Leser rein.
Das sind alles Java-Stromdetails, die sind jetzt nicht so wichtig.
Wichtig ist, ich kann jetzt also über diese Variable innen,
kann ich jetzt Daten saugen von Wikipedia sozusagen
Okay, dieses zeilenweise Saugen von Daten passiert hier,
das ist auch so ein Standard-Java-Idiom, ich lese immer eine Zeile,
gucke, ob die nicht nall ist,
dann führe ich sie hinzu und tue ein Zeilenoperanz.
Das ist jetzt auch eigentlich keine schwarze Kunst. Und auch
dieses Readline kann natürlich viel schlagen. Also stellt euch vor,
ihr habt die Connection sinnvoll eröffnet bekommen, habt einen Strom bekommen,
ihr fangt an, Daten zu saugen,
dann kommt euer Kollege und stolpert über euer Kabel und dann ist die Verbindung weg oder so.
Deswegen kann hier auch jederzeit eine Acception auftreten. Okay,
und wenn man fertig ist, dann sollte man diese Verbindung wieder schließen
Auch das kann fehlschlagen, was man da noch sinnvoll machen kann,
weiß ich auch nicht, weil man sollte es zumindest versuchen.
Und am Ende wird dann alles, was ich gelesen habe,
einfach in den String umgewandelt und da habe ich eben
diesen riesigen Monster-Text mit den ganzen furchtbaren Dingen drin,
die ich eigentlich gar nicht haben will.
Ja? So. Okay, ist ja vielleicht ganz spannend,
was hier passiert, aber wir wollen jetzt uns um diese Acceptions kümmern.
Also wir haben jetzt hier einen Quelltext, der,
wenn man ihn so von oben nach unten runter liest,
beschreibt, was im Normalfall passieren soll.
Und jetzt muss ich mich eben darum kümmern,
was ist, wenn das nicht geht?
Wie mache ich das? Ich schreibe einen Tri-Blockdown.
Ich sage also, versuch das doch mal.
So bis hier ungefähr
Dann können wir uns darum kümmern, uns zu überlegen,
was machen wir denn jetzt, wenn Dinge schiefgehen?
Also was war die erste Acception? Das war diese Malformed UIRL Acception. Also Catch,
Malforne, wie schreibt man es denn mit großem oder kleinem F?
Da ist sie. So, jetzt hatte ich ja schon gesagt,
dieser Fehler hat nichts damit zu tun,
ob man ein Internet geht oder nicht,
sondern da geht es jetzt nur darum,
habe ich mich da als Programmierer vertippt oder nicht.
Das heißt, ich würde jetzt nicht irgendwie den Benutzer sagen,
hey, pass auf, es ist gerade was schiefgegangen,
versuch es doch in fünf Minuten nochmal.
Das würde keinen Sinn machen, weil der Fehler ist ja
immer noch im Programm drin. Also hier kann ich eigentlich nur sagen,
ich schmeiße mal irgendeine ungeprüfte Acception und sag mal irgendwie,
Was man gerne macht, ist, keine Ahnung,
HTTP-Shoot, on ways work, Review-Code oder was weiß ich.
Also wenn dieser Fehler irgendwie auftritt, dann heißt es,
es ist in meinem Programm irgendein Bug, der behoben werden muss.
Wir können denen nicht informieren, oh, da wird ein New,
weil ich immer mit anderen Programmiersparen zu tun habe,
wo die das New nicht mehr haben.
So, ne? Okay. Gut,
ihr seht also, hier ist doch schon mal ruhig,
ihr beschwert das sich jetzt nicht mehr.
Ich habe mich ja so in diese potenziell Auftritte auftretende Exception gekümmert.
Was kann jetzt hier noch schiefgehen? IO-Exception,
machen wir das doch mal als nächstes.
Hm. Schau, was kann man denn jetzt Sinnvolles machen?
Also man könnte jetzt in diese Description natürlich was reinschreiben.
Das wäre vielleicht ein sinnvoller Schritt, den man als erstes machen könnte.
Sagen wir mal, Internet-Problems oder so im Internet-Problems.
Kannst du jetzt nicht besonders viel sagen, aber immerhin.
Und dann formatiere ich das mal. So,
das ist also unser erstes reales Beispiel,
wie man so
ein Try-Catch schreiben kann
Warum das mal ausschwimmen? Ich meine,
da müsste ich jetzt wirklich mal meine Internetverbindung trennen,
aber das kann ich auch mal machen.
Also einmal das hier wegnehmen. Einmal ganz kurz gucken.
Ob das jetzt im momentanen Zustand funktioniert. So. Ja,
Cat war doch immer ganz nett. Das funktioniert und dort funktioniert auch
. Ja, ja, okay, scheiße, funktionieren.
Dann, wie trenne ich den? Ach hier, Verbindung
trennen. So, jetzt bin ich nicht mal im Internet.
Jetzt starte ich das bei mir noch mal.
Mal gucken, was jetzt passiert
Oh. Das ist ja interessant. Illegal State Exception,
die haben wir heute noch gar nicht gesehen, oder?
Illegaler Staat oder illegaler Status wird es wahrscheinlich sein.
Wo ist der denn aufgetreten hier? Ah. Kennt sich irgendjemand von euch
mit regulären Ausdrücken aus? Einmal Handtuch, regulärer Ausdrücke?
Okay, gut. Weiß jemand, oder ich meine,
vielleicht könnte es auch an dem Namen euch überlegen.
Also welchen Sinn hat diese Methode Retain First Sentence
Also was könnte diese Methode versuchen? Also ich habe ja jetzt
diese Description, da steht jetzt einfach nur drin, Internet-Problems.
Und was versucht jetzt dieses Retain first sentance, ja?
Ja. So wie ihr auf den Satz seid,
wenn es weiter ist, wie im Album.
Genau, genau. Also er versucht, irgendwie so eine Struktur
zu finden, The Dog, bla bla bla, Punkt.
Und sowas ist hier natürlich nicht. Jetzt könnte man darum
irgendwie rumprogrammieren und sagen, okay,
dann tun wir halt auch einen Punkt in unsere Ausgabe rein.
Das ist natürlich jetzt sehr gehackt hier, ne?
Also dann verschwindet wahrscheinlich dieser Fehler. Das ist natürlich nicht
so ganz im Sinne des Erfinders. Aber einfach,
dass wir unsere Vermutung aber besteht,
Ach so, ah. Ich glaube, wir brauchen noch
eine Lehrtaste hinter, weil danach dann ja davon ausgegangen wird,
dass der zweite Satz kommt.
Okay, immerhin. Gut, er stürzt nicht mehr ab.
Aber so wahnsinnig sauber ist es natürlich nicht. Also diese Methode sagt,
oder letzten Endes wird es ja aufgerufen von der Methode, ich eroben.
Diese Methode sagt, gib mir ein Tier und ich gebe dir eine Beschreibung.
Ich gebe dir eine Beschreibung dieses Tiers und jetzt einfach
eine Fehlermeldung als Beschreibung eines Tiers zurückzugeben,
ist ja irgendwie nicht so wirklich sauber, oder?
Also ich fände es irgendwie sauberer,
wenn man eine Exception zurückgibt zum Beispiel
Das heißt, vielleicht können wir an dieser Stelle sagen,
vielleicht ist es gar nicht so sinnvoll, diese Acception hier selber zu behandeln.
Also diese Acception hier zu behandeln, finde ich extrem sinnvoll,
weil ich halt der Meinung bin,
das ist ja ein Punkt, was heißt behandeln,
ich kann eigentlich, ich kann sie hier gar nicht,
ich kann sie nirgends im Programm sinnvoll behandeln,
weil es wäre ja ein Programmierfehler, wenn sie auftritt.
Diese Acception kann man im Prinzip sinnvoll behandeln,
aber vielleicht ist hier nicht die richtige Stelle dafür.
Vielleicht sollte ich irgendwie lieber meinen Klienten sich darum schümmern lassen.
Ich weiß noch nicht, vielleicht ist das irgendeine grafische Oberfläche,
vielleicht soll dann irgendwie ein Fenster aufploppen oder so.
Das kann ich an der Stelle hier ja gar nicht wissen.
Ich bin ja einfach nur so ein blöder Service,
der überhaupt nicht weiß, wie sieht denn eigentlich die Programmoberfläche aus?
Also ich will diese, ich will diese O-Exception eigentlich nicht
selber behandeln, weil ich da nichts Tolles machen kann.
Nehme ich das mal immer weg. Ja,
aber jetzt ist es ja jetzt nicht übersetzbar,
diese Methode,
Gibt es denn jetzt irgendeine Alternative zu sagen?
Also hier kann eine Exception auftreten. Ich selber kann sie
aber eigentlich gar nicht behandeln. Was mache ich denn stattdessen?
Ja. Explizit weiterleiten. Weißt du, wie die Syntax
dafür ist? Die Liebe. Und dann... Also du würdest
sie quasi auffangen wollen und dann irgendwie wieder weiterschmeißen wollen.
Dann hätten wir, glaube ich, dasselbe Problem wie vorher.
Ja, eine andere Idee, ja.
Genau, sehr schön. Also ich kann Also,
wir haben ja einen SE- einzelnen Begriff, der Signatur eingeführt.
Wir haben gesagt, eine Methode hat irgendwie einen Namen und hat sich
irgendwelche Parameter und je nach Signaturbegriff tun wir manchmal noch den Rückgabetyp dazu, oder nicht?
Und jetzt erweitern wir diesen Signaturbegriff so ein bisschen.
Ich gucke mal kurz, ob Equipse das für mich machen kann.
Kann ich ihm sagen, ach guck mal,
es gibt hier sogar sowas, Ed Throws Declaration.
Mal sehen, ob er das sinnvoll hinbekommt.
Tatsache. Ja, ich kann auch so einer,
bei einer Methode oben angeben, diese Methode schmeißt möglicherweise eine IO-Exception.
Ja, und jetzt ist hier, ich will das weghauen.
Jetzt sind hier die ganzen roten Striche weg. Das heißt,
der Java-Compiler ist jetzt zufrieden. Es kann hier zwar eine IO-Exception auftreten,
ich selber behandle sie auch nicht,
aber Ich melde hier sozusagen dem Klienten über das Typsystem,
hey, du musst dich wahrscheinlich irgendwie darum kümmern.
Aber ich habe jetzt erst mal meine Pflicht sozusagen getan.
Ja, dann schauen wir noch mal, wer ruft denn dieses Konsult-Wikipedia auf?
Das war ja diese allgemeine Methode hier oben, ne, hier.
Gut, wir sind ja immer noch in derselben Klasse,
ich weiß ja immer noch nicht,
ob das später mal eine Google sein wird oder irgendwas anderes.
Ich kann hier immer noch nichts Sinnvolles mit Ioway Acception machen.
Was mache ich denn jetzt? Ich kann sie hier nicht
sinnvoll behandeln. Ich habe sie bekommen von dem Dienstlasser,
den ich eben verwendet habe, also die Methode von mir selbst
und ich kann selber jetzt nichts damit machen.
Was mache ich jetzt als nächstes?
Transferleistung von eben
Ja, du weißt es natürlich, das ist ja eben schon mal vorgeschlagen.
Sonst keiner. Okay. Also, liegt weiter nach oben.
Genau. Nicht mein Problem. Soll sich doch der kleine Daumen kümmern.
Ja. So, jetzt ist das hier auch weg.
Und jetzt sind wir jetzt aus der Schuld.
Ich gucke mal zu, was ist das hier noch?
Ah. Okay, ich wollte eigentlich gar nicht darüber reden. Also,
wenn ihr irgendwie ein Tier angeht,
was dann irgendwie weitergeleitet wird zu einem anderen,
zum Beispiel Kau wird ja zu Kettel weitergeleitet,
dann muss ich natürlich nochmal Wikipedia fragen, hey,
gib mir doch mal den Text zu Kettel.
Dann kann es hier natürlich genauso schief gehen.
Das heißt, hier muss ich genauso sagen,
ich weiß nicht, was ich damit machen soll.
Ich sage einfach, meinem Klienten kümmert du dich nochmal darum
So. Okay. Bis hierhin erstmal fragen. Also wir haben
jetzt zwei verschiedene Arten gesehen, wie man mit Acceptions,
die im eigenen Methodenrum auftreten kann, umgehen kann.
Entweder kümmere ich mich selber drum. Oder ich sage,
ich kann mich nicht darum kümmern, ich schmeiße die weiter an meinen Knien.
Diese beiden Möglichkeiten gibt es. Okay, keine Fragen.
Glaubt ihr, dass das gesamte Projekt jetzt übersetzbar ist oder
gibt es jetzt möglicherweise anderswo Fehler?
Ich habe jetzt ja hier die Signaturen geändert.
Also diese Methode, die er vorher gesagt hat,
gib mir einen String und ich gebe dir auch einen String zurück.
Die Signatur hat sich jetzt plötzlich geändert.
Jetzt steht hier noch, Achtung, Achtung,
möglicherweise schmeiße ich
eine IO-Exception
Könnte das jetzt irgendeinen Einfluss auf den Rest des Projekts hauen?
Ja. Und jetzt einfach den Haufen hochwerten,
Tage erkennen, die ich hier erkennte.
Genau, der Klient dieser Methode muss sich jetzt darum kümmern.
Das heißt, ihr Klimps wird schon von alleine festgestellt haben,
dass es hier irgendwo ein Problem gibt.
Seht ihr, jetzt gibt es hier in diesem Rappeln-Problem.
Hierzu vielleicht kurz die Zeit, dass du uns einmal kurz den Rappel angucken.
Ihr seht, das ist super trivial, oder? Also,
die Zeile, die eingegeben wurde,
liefere ich sozusagen als Tier an diesen Animal-Surfern und sage,
beschreibe mir doch mal bitte dieses Tier.
Dann kommt diese Description zurück und dann schreibe ich diese Description
auf die Konsole.
Also einfacher geht es ja
fast nicht
Jetzt wird sich hier wieder beschwert. Ihr Clip sagt,
Achtung, Achtung, Achtung, Fred, hier kann ja eine IO-Acception auftreten.
Du machst aber gar nichts mit dieser IO-Acception.
Das ist ja irgendwie blöd, ne? Ja. Jetzt
haben wir wieder die Wahl. Jetzt können wir sie entweder
selber behandeln oder wir sagen, unser Klient soll sie behandeln.
Wir sind wahrscheinlich wieder unser eigener Klient. Wo wird denn
dieses Process Line aufgerufen? Das wird hier aufgerufen.
Ich glaube, solange man innerhalb derselben Klasse ist,
macht das jetzt nicht so einen riesigen Unterschied.
Ich behandle die einfach mal hier unten. Ich sage,
ich will hier unten mit dieser IO-Acception umgehen.
Also, so. Catch,
IO-Acception,
Ja, was machen wir denn dann?
Vielleicht machen wir einfach mal. Hier, jetzt, ähm,
sehr, peers to be problem with the engine match.
So. Gut. Ach, jetzt kennt er, glaube ich,
den Typen nicht, kann nicht nur sagen,
er soll den Typ importieren.
Ja. So, gibt es jetzt noch irgendwo Fehler?
Nö, dann starten wir das doch mal.
Das ist falsche Klasse
So. Cat. Jo, toll, tolles Programm.
Jo. Okay, aber zumindest sagten wir,
was ich tun sollen. Wir können das mal so,
ich lasse das Programm jetzt mal laufen und jetzt behebe ich mal das Problem,
weil ich als Benutzer verstehe jetzt ja,
was das Problem ist.
Und sag mal, ich will mich jetzt hier mal wieder
mit dem Internet verbinden. Bumm, bumm, bumm,
bumm. Sollen wir mal warten,
bis wir
die Internetverbindung haben
Ja, lieber Kreis, ich hoffe, es funktioniert gleich.
Sonst haben wir, okay. Und dann schauen wir,
dass es wieder geht. Ja, toll, oder?
Also ich musste noch nicht mal das Programm neu starten oder irgendwas.
Das Programm ist also nicht einfach abgestürzt,
das wäre ja furchtbar, wenn es einfach sich komplett beendet,
nur weil das Internet gerade nicht da ist.
Sondern ich sage dem Benutzer irgendwie, was er tun soll
und dann kann er es später nochmal probieren.
Das ist doch ganz nett. Okay. Habt ihr zu
dem Thema noch Fragen? Try, Catch, Throw
, Throws
Jetzt nicht, okay. Dann war ja vorhin diese
eine Frage, wann braucht man eigentlich das Final Lied?
Habe ich mir nochmal schnell einen Link rausgesucht? Da habe ich,
ich hatte jetzt nicht genug Zeit, da ein Anwendungsbeispiel zu programmieren,
aber das ist eigentlich so das Standardbeispiel, das gucken wir uns nochmal ganz kurz an.
Also wir machen in SE1 und SE2 ja gar nichts mit irgendwie nebenläufigen Prozessen,
also dass irgendwie mehrere Dinge gleichzeitig passieren,
aber wenn ihr das später vielleicht irgendwann mal macht,
dann ist es oft so, dass ich sage,
ja, ich habe irgendwelche Codeabschnitte,
die dürfen nur betreten werden,
wenn ich ein gewisses Log,
das ist eine gute Übersetzung dafür
Schloss. Wenn ich ein gewisses Schloss in der Hand halte,
also nur einer darf so ein Schloss gleichzeitig in der Hand halten.
Ich sage also, okay, ich möchte dieses Schloss in der Hand halten.
Und wenn dieser Aufruf zurückkehrt, dann ist garantiert,
dass ich der Einzige bin, der dieses Schloss in der Hand hält,
dann kann beliebig viel komplizierter Quelltext ausgeführt werden.
Und ich muss sicherstellen, dass ich am Ende dieses Schloss wieder hergebe,
wenn ich mit jemand anders was damit machen kann.
Und warum ist es jetzt wichtig,
dass wir das mit einem Tribe Finally machen,
dass ich nicht einfach schreibe, el.blog,
ganz viel interessanter Code und dann el.unlock.
Das ist deswegen wichtig, war ja in diesem Code
potenziell beliebig viele Acceptions auftreten könnten.
Das könnten IO-Acceptions sein, es könnten aber auch Milepointer-Acceptions sein,
also es können sowohl Programmier als auch Umgebungsfehler sein
Die Umgebungsfehler sind aber die Schlimmeren. Also stellt euch vor
, hier passiert eine IO-Exception. Nur dann wird irgendwie zum
Klienten zurückgegangen, der kümmert sich irgendwie um die IO-Exception.
Aber wir halten immer noch dieses Schloss, das wäre ja
eine Katastrophe. Ja, und dieses Finaly garantiert eben,
selbst wenn hier eine Exception ausgelöst wird, wird das,
was in dem Finaly steht, trotzdem noch ausgeführt.
Das braucht ihr also immer, wenn ihr sagt,
ich habe irgendeine Ressource. Ich weiß genau,
wenn ihr eine Datei zum Beispiel öffnet und sicherständig sein wollt,
dass ihr auf jeden Fall wieder schließt oder so.
Ihr sagt, ich will diese Ressource haben,
dann macht ihr euren Schreiblog und im Final Blog
gebt ihr diese Ressource wieder dem System zurück
Seid ihr nicht ganz so gewöhnt, weil für die Ressource
Arbeitsspeicher müsst ihr das ja nicht machen. Dafür gibst du den Gabbage-Collector.
Aber es gibt keinen Gabbage-Collector für Logs oder für File-Handles oder so.
Das müsst ihr in Java eben dann doch noch ein bisschen von Hand machen.
Okay. Ja. Aber den meinen Verbrauch und Herrn. Ich glaube,
die Frage war eher, ob man mich einfach in den Prof,
der zweite Kopf das aushalten kann. Ja,
aber das Problem ist, wenn du,
ich habe das ja eben schon versucht zu sagen,
also wenn du diesen Finally Block nicht hast,
sondern einfach, die konnten nur hier unten hinschreibst,
dann wird dieser Code nicht ausgeführt,
wenn vorher mit einer Acception aus der Methode
ausgestiegen wird
Wenn du mitten im Rumpf einer Methode bist und es fliegt eine Acception,
dann wird der Rest eine Methode nicht mehr ausgeführt,
genauso als wenn du einen Return schreibst oder so.
Und wenn man sicher sein will, dass selbst,
wenn man mit einer Acception aussteigt,
der Code trotzdem noch ausgeführt wird, dann bauen man das Feindeli.
Das ist der Sinn davon. Okay,
dazu habe ich natürlich gleich einen Puzzleor, weil es so
ein lustiges Thema ist, brauche ich mal eine Puzzlos hier.
Weil ich habe leider kein sinnvolles Beispiel zu dem Finaly jetzt heute hier,
aber ich dachte, ich bringe euch mal sowas mit.
Also ich habe eine Methode. Diese Methode liefert True zurück,
aber auf jeden Fall, egal wie auf der Methode ausgestiegen wird,
soll Fords zurückgeliefert werden. Ja. Ihr seht schon,
Eclipse sagt, das ist wahrscheinlich nicht so eine gute Idee,
aber vielleicht mal als kleine spannende Unterhaltung.
Wer glaubt denn, dass da True zurückgeliefert wird,
aus dieser Methode? Einmal Handhof, er glaubt,
dass True zurückgeliefert wird, weil da steht ja,
ich will Return Schumacher im Normalfall, ja.
Okay, vielleicht von Fental. Wer glaubt, dass Fouls
zurückgeliefert wird? Boah, vielleicht zehn oder zwölf Hände,
okay. Das kann man nicht wissen,
ohne das einmal ausprobiert zu haben, ja,
man muss einmal ausprobieren.
Also bitte schreibt so
einen Code niemals
Es kommt tatsächlich fort zurück. Und Eclipse warnt mich hier,
glaube ich, dass das irgendwie nicht so wirklich sinnvoll ist.
Ja, ja. Also man sollte innerhalb eines Final-Blogs
niemals irgendwie Exception schmeißen oder returnen oder so.
Das bringt das ganze System so ein bisschen in Zwang.
Okay. Ja, jetzt haben wir noch noch eine weitere Sache,
die ich mit euch machen wollte,
weil das auch in der Übung daran kommt.
Wir kriegen hier also eine IO-Exception. Das könnte erstmal ja
alles mögliche sein. Vielleicht hat das was mit dem Dateisystem zu tun.
Vielleicht hat das was mit einer Datenbank zu tun.
Vielleicht hat das was mit dem Internet zu tun.
Wir wissen es nicht genau. Vielleicht wäre es irgendwie schöner,
wenn man eine Exception kriegt, die sagt,
es gab ein Problem mit dem Wörterbruch oder mit dem Lexikon.
Lexikon heißt er, glaube ich, in Zyklopädia.
Es gab ein Problem mit dem Lexikon
Das sagt dann vielleicht ein bisschen mehr,
weil es geht ja hier fachlich in dieser Anwendung um ein Lexikon,
in dem halt so Begriffe nachgeschlagen werden.
Ich würde also jetzt gerne mal mit euch eine eigene Acception-Klasse bauen,
damit man nicht so generische IO-Exceptions oder sowas durch die Gegend wirft,
die ja alles mögliche bedeuten könnten.
Okay, dann schreiben wir uns diese Klasse noch einmal ganz kurz.
Eine eigene Acception-Klasse. Wie wollen Sie nennen?
Nennen wir Sie Enzyklopedia-Exception. Ich hoffe, ich habe mich
nicht vertippt.
So. Okay
Ich weiß gar nicht, ob Guido diese Folie
gezeigt oder übersprungen hatte. Man muss sich jetzt entscheiden.
Will ich eine Acception-Klasse schreiben, die für Programmierfehler steht?
Also sowas wie eine Nightpointer-Acception oder so? Oder soll es
eine Accession sein, mit der man sinnvoll im Programm umgehen kann?
Dass irgendwie, ja, wenn ich das Beispiel in der
Internetverbindung jetzt sage, ist ja irgendwie klar.
Also kann man sich von dieser Acception sinnvoll erholen?
Was würdest du sagen? Will ich hier? Geht es
hier um Programmierfehler oder um Umgebungsfehler mit dieser Enzyklopädia-Acception?
Ja. Genau, eine Umdingungsfehler. Und Umgebungsfehler erkennt man
daran, dass sie von Acception erben.
Wenn es jetzt ein Programmierfehler gewesen wäre, würde ich von
Runtime Acception erben. Könnt ihr euch sonst die Folie
nochmal angucken
Okay, dann brauchen wir irgendeinen Konstruktor. Ich mache jetzt mal
eine ganz einfache Variante, wo einfach nur ein String übergeben wird,
dass ich in dem String wieder steht, was schiefgelaufen ist.
Normalerweise würde man dann noch mehr Informationen reintun. Vielleicht,
welches Tier gesucht wurde oder welche URL versucht wurde oder so.
Ach, wisst ihr was, das machen wir einfach mal.
Ich würde euch ja zeigen, wie man es vernünftig macht,
weil es so ein String Animal, String, URL,
String Message.
So, dann rufen wir einmal unseren Superkonstruktor auf.
Es gibt also in Acception einen Konstruktor, der ein String entgegennimmt.
Dann kann ich zumindest diesen generischen String hochleiten,
an den kann man
später rankommen
Und dann machen wir uns nochmal ganz kurz ein Animal und eine URL.
Das ist jetzt hier alles ein bisschen sehr gehetzt,
aber ihr könnt euch vielleicht später vorstellen,
dass man dafür dann auch noch entsprechende Ghetter anbietet.
Aber es ist immer schön,
wenn man so ein Acception-Objekt in der Hand hat,
dass man dann irgendwie dem Acception-Objekt sagen kann, sag mal,
gib mir doch mal nochmal ein paar sinnvolle Informationen.
Welche Zutaten jetzt zu den Problemen geführt haben,
denn wenn ich jetzt einfach nur diesen String sehe,
fangen dann nachher benutze, an diesen String zu pasen und dann,
das ist nicht so schön.
Stell dir vor, du hast hier noch Get Engine und
Get Whirl, das schreibe ich jetzt nicht mehr.
Okay, dann gehe ich jetzt wieder an meinen Animal Service
Und ich will jetzt kein IO-Exceptions mehr schmeißen. Vielleicht nehme ich
jetzt mal diesen String und lösche den mal überall raus.
Kann man hier irgendwie schnell Find and Replace machen,
wie ist da der Shortcut in den Clips?
Steuerung F? Okay, also ich will dieses Throws IO-Exception will ich
nirgendwo mehr haben, sonst übersehe ich gleich eine Stelle.
Jetzt weiß ich wieder, wo ich mich darum schümmern muss.
Okay, also was ich jetzt mache, ist etwas,
ich hatte ja eben gerade gesagt,
wir kümmern uns nicht um diese IWAX-Heption, aber jetzt tue ich es wieder.
Ist ja irgendwie vielleicht ein bisschen inkonsistent, aber gut.
Ich kümmere mich jetzt wieder um diese IO-Exception. Und alles,
was ich jetzt tue, ist aber jetzt diese fachliche Exception zu werfen.
Ich sage jetzt also Throw, New, Zyp, Clopedia,
Acception, das Animal heißt so, die URL heißt,
ach guck mal, jetzt habe ich den String gar nicht,
das ist ja blöd, ne?
Dann baue ich mir den String vor noch einmal ganz kurz zusammen,
über L-String, ist dieser String, ich will ja,
das ist ja bei uns so schön,
die Information aus der Exception rauskriegt.
So. Gibt es jetzt noch irgendwo ein Problem,
warum will er das nicht formatieren?
Muss ich es halt von Hand machen. So,
da tue ich also jetzt diesen URL-String rein und die Message ist irgendwie,
keine Ahnung, Internet-Problems oder was auch immer.
So. Ach. Diese Variante URL-Stream gibt es hier unten ja gar nicht.
Die muss ich mir dann natürlich außerhalb des Trialcatchs zusammenbauen.
Ja. Hier kann ja keine Exception auftreten.
Also einfach nur zwei Strings zu konkordinieren. Die Tatsache,
dass das hier eine URL ist, ist ja,
ist ja Java völlig egal.
Okay. Er will es immer noch nicht machen.
Was ist jetzt das Problem? Ah, genau.
Also ich schmeiße einer in Strictlopedia-Acception und behandle sie nicht.
Natürlich nicht. Okay, was muss ich jetzt machen,
damit der Compiler das akzeptiert, dass sich diese Enzyklopedia-Acception
hier schmeiße
Das ist dieselbe Antwort schon wieder, ne? Ja. Genau,
ich muss hier oben ankündigen, dass ich die schmeiße,
dann sage ich das um Eclipse,
dass ich das mit davon alleine hinschreiben soll.
So, okay, jetzt geht es woanders wieder Probleme.
Hier ist dasselbe Problem. Okay, haben wir noch irgendwo
ein Problem? Hier haben wir wieder dasselbe Problem.
So. Hatte ich nicht irgendwo hier unten noch... Nee,
das war das Read Direct, das habe ich gerade gemacht, oder?
Ja, genau, das hatte ich gerade gemacht. Alles klar,
dann gehen wir jetzt wieder in unseren Rappel rein und sagen,
ich fange kein IO-Exception mehr, sondern eine En-Zyklopedia-Acception, genau.
Okay, und dann könnte man ja sogar das hier alles
mal wunderbar ausgeben. Also Ex-Punkt-Gärten-Messe. Ich spiele,
glaube ich, diese Message noch mal ein bisschen schöner machen,
dass wir vielleicht sagen, cood not low cage,
ob es... Das hat mir zu viel weggeneriert,
verdammt.
Mir so vielleicht, ja, dann ist die Message ein bisschen schöner.
Okay, dann probieren wir nochmal, ob das jetzt
alles geklappt hat, dass wir nichts kaputt gemacht haben.
So. Achso, ich habe ja eine Internetverbindung, ha.
So, das geht immer schneller.
Ah,
seht ihr
Okay, ich finde diese Meldung ein bisschen sinnvoller, ehrlich gesagt.
Dann kann man vielleicht gucken, liegt das jetzt wirklich,
vielleicht liegt es ja auch nur an Wikipedia.
Ich könnte jetzt also in den Browser reingehen,
ganz normal als Benutzer und gucken, ist wieder gerade Wikipedia down oder so,
sonst hätte ich jetzt gar nicht gewusst, dass es überhaupt mit Wikipedia gemacht wurde.
Ja, okay. Gut, das ist interessant,
das Cat geht aber immer noch, oder? Ja,
ja, also der merkt sich ja so in dieser Map,
alles, was er jemals schon mal im Internet nachgeguckt hat,
das muss er nicht nochmal nachgucken.
So, oh Gott, das ist ja schon wieder unglaublich spät,
dann gehe ich vielleicht nochmal ganz kurz, wo ist die spannendste Stelle,
über die man vielleicht nochmal Fragen stellen kann,
das war ja die hier, ne?
Genau, wir haben jetzt, glaube ich,
alles gemacht, was ihr für die Übung braucht,
bis auf diese Sache mit den Paketen beziehungsweise Modulen,
das müsst ihr euch dann vielleicht nochmal angucken,
ohne dass ihr jetzt was von mir dazu gesehen habt.
Gibt es hierzu mal Fragen, Try Catch, Frow,
Throws. Okay, vielen Dank bis nächste Woche