JAVA & Objektorientiertes Programmieren 2

Erweiterung der ersten Kartei

Erweiterung der ersten Kartei


Fichier Détails

Cartes-fiches 203
Langue Deutsch
Catégorie Informatique
Niveau Université
Crée / Actualisé 19.01.2017 / 09.01.2024
Lien de web
https://card2brain.ch/box/20170119_java_objektorientiertes_programmieren_2
Intégrer
<iframe src="https://card2brain.ch/box/20170119_java_objektorientiertes_programmieren_2/embed" width="780" height="150" scrolling="no" frameborder="0"></iframe>

Was für was stehen die drei Basisklassen für Exceptions?

Error: Für nicht behebbare, schwerwiegende Fehler (in der Regel keine explizite Behandlung)
Exception: Für behebbare und (eigentlich) erwartete Fehler (Behandlung wird erzwungen (checked)
RuntimeException: Für behebbare, eher nicht erwartete Fehler (Behandlung dieser Exception ist optional (unchecked)

Unbehandelte Fehler werden letztlich wo oder wie behandelt?

Von der Java Virtual Maschine in Form einer Konsolenausgabe (Stacktrace)

Die folgende Ausgabe (siehe Bild) bezeichnet man als Stacktrace.

Wozu dient sie und wann tritt sie auf?

Die Ausgabe erfolgt auf der Konsole und ist typisch für Exceptions welche nicht behandelt wurden / werden konnten.

Enthält nützliche und sehr präzise Angaben wo die Exception aufgetreten ist.
Tipp: Von oben nach unten lesen, die erste Klasse aus der eigenen Codebasis (hier ch.hslu.*) ist ein guter Einstiegspunkt

Zeige ein Beispiel einer checked Exception und was ist hierbei zu beachten?

Wichtig: throws-Deklaration zwingend!

(siehe Bild)

Zeige ein Beispiel einer unchecked Exception.

Ist hier eine throws-Deklaration zwingend?

Nein. Dies ist nur bei einer checked Exception zwingend!

(siehe Bild)

Wird die Exception geworfen, wird die Methode beim throw-Statement sofort verlassen / abgebrochen (dies gilt auch für unchecked Exceptions)

Wie sieht ein Beispiel eines Handlings einer checked Exception aus?

(siehe Bild)

Wieviele try-Blöcke und wieviele catch-Blöcke gibt es für unterschiedliche Exceptions?

Es gibt nur einen try-Block, aber es darf mehrere catch-Blöcke für unterschiedliche Exceptions geben.

Der erste zutreffende catch-Block wird als einziger ausgeführt

Was ist bei den catch-Blöcken wichtig zu beachten?

Exceptions sind verebt und somit polymorph!
Mehrere catch-Blöcke müssen darum nach Typ sortiert werden:
Spezialisierte Exceptions vor den allgemeinen Exceptions!
Ansonsten "catched" eine generelle die spezifische Exception!

Ist der finally-Block zwingend bei Exceptions?

Nein, existiert ein catch-Block, dann ist der finally-Block optional (typischerweise für "Aufräumarbeiten" vorgesehen.
Exisitert kein catch-Block (eher selten) muss ingegen ein finally-Block folgen

Was passiert bei unchecked Exceptions, wenn man sie nicht behandelt?

Werden automatisch an den aufrufenden Kontext weitergeleitet

Was passiert, wenn man checked Exceptions nicht behandeln möchte/kann?

Wenn man sie nicht behandeln möchte/kann, kann man diese explizit an den aufrufenden Kontext weiterleiten:

- Exception muss mit throws im Methodenkopf deklariert werden, so als ob sie in dieser Methode geworfen würde!
- Entscheid wird also bei der Implementation getroffen (statisch)

Sollte man die Exceptions in der JavaDoc dokumentieren?

Unbedingt!

Ist es sinnvoll Exceptions für eigentlich normal, erwartete Spezial- oder Sonderfälle zu verwenden?

Nein, wirklich nur für Ausnahmen!

Was gilt beim Einsatz von eigenen Exceptiontypen?

So wenig wie möglich, so viel wie nötig.
Möglichst bereits vorhandene Typen verwenden.

Sollte man ineinander verschachtelte try/catch-Blöcke eher fördern oder verhindern?

Verhindern! Code wird extrem unübersichtlich und schwer verständlich

Wann implementiert man leere catch-Blöcke?

Niemals!

Ist Unit Testen notwendig beim Exceptionhandling?

Ja, unbedingt!

Wie funktionierte die alte Technik (quasi von Hand gestrickt) des Exception Testing?

- Exception provozieren (hier mit unerlaubtem Parameter)
- Exception selber fangen (catch) und danach auswerten
Wichtig: Explizites fail, wenn Exception nicht eintritt!

(siehe Bild)

Was ist die einfache neuere Technik um Exceptions zu testen? Was sind seine Vorteile/Nachteile?

- Per Annotation definieren welche Exception erwartet wird
- Exception provozieren (hier mit unerlaubtem Parameter)

Vorteile: sehr einfach zu implementieren und leicht verständlich
Nachteile: kein Zugriff auf Exception um inhaltliche Prüfung zu machen!

(siehe Bild)

Was ist die "state of art" Methode um Exceptions zu Testen? Was sind die Vorteile?

- Mit @Rule richtet man quasi eine "Falle" ein
- Pro Testfall die ExpectedException spezifisch konfiguriere
- Exception provozieren (hier mit unerlaubtem Parameter)

Vorteil: Einfach, und man kann die Exception inhaltlich prüfen!

(siehe Bild)

Für die Kontrolle unserer Programme kann man mit System.out.println(...) Ausgaben auf die Konsole machen. Nenne eine sinnvollere Methode und weshalb System.out.println(...) nicht sinnvoll ist.

Logging-Technologie

Nachteile System.out.println(...):
- Konsole ist bei GUI-Applikationen meist nicht sichtbar
- Konsole hat einen beschränkten Ausgabebuffer (Queue!)
- Ausgaben gehen nach Termination des Programmes verloren
Bei Serveranwendungen auch sinnlos:
- Vervielfachung der Datenmenge (Output "rauscht" durch)
- Niemand sitzt im Serverraum und guckt zu! Oder?

Was ist der Vorteil von Logging-Frameworks?

Sie bieten eine definierte, einfache Schnittstelle, um in einem Programm wichtige Informationen "loggen" zu können.

Typisch unter verschiedenen LevelsErrorWarningInfoDebugTrace, etc.

Kann man festlegen wohin die Logs gehen?

Ja, wohin diese Logs gehen kann per dynamischer Konfiguration (also ohne Codeänderung und Kompilation) festgelegt werden. Bsp:
- in Dateien schreiben
- über das Netzwerk an zentralen Logging-Server übermitteln
- oder bei verteilten Anwendungen direkt in Clouddienste übermitteln
- und während der Entwicklung auf die Konsole schreiben

Wie funktioniert Apache Log4J 2?

1. Pro Klasse in eine Variable den Logger holen:
private static final logger LOG = LogManager.getLogger(MyClass.class);

2. Mit den verschiedenen Levels loggen, was man loggen will

Wie oft sollte man beim Exceptionhandling Loggen?

Es ist häufig eine gute Idee, jede Exception im Rahmen ihrer Behandlung mindestens zu loggen!

Im produktiven Betrieb einer Applikation lässt man z.B. ausschliesslich Logs der Level Error und Warning persistieren. Die Dateien bleiben im Idealfall leer (weil keine Fehler)

Tritt ein unerwarteter Fehler auf, kann man aufgrund von welchen Dateien bereits nützliche (und welche) Rückschlüsse ziehen (sofern man sie implementiert hat)?

Aufgrund der Log-Dateien, sofern man das Logging beim Exceptionhandling gut implementiert hat.

Man kann dann Rückschlüsse auf, wann der Fehler und wo er aufgetreten (Stacktrace) ist
Zur weitere Fehlersuche kann man den Loglevel z.B. temporär erhöhen um mehr Kontextinformationen zu erhalten

Anforderungen für ein Auto mit Motor:
- Auto kann (inkl. Motor) ein- und ausgeschaltet werden
- Motor soll Status und Störungen an Auto melden

Das führt zu Beispiel im Bild:
- Auto hat Motor
- Damit Motor Status über notifyMotorStatus(...) melden kann benötigt er eine Referenz auf Auto

Was ist hier das Problem?

Zirkuläre Beziehung und zu starke Kopplung!

Weshalb sind zirkuläre Beziehungen nicht sinnvoll?

Zirkuläre Beziehungen sind nicht nur eine sehr starke Kopplung, sondern haben noch weitere sehr gravierende Nachteile:

- zirkulär verbundene Elemente sind nicht mehr teilbar (können nicht mehr einzeln verwendet werden)
- sind nur innerhalb desselben Projektes technisch überhaupt machbar (keine unabhängige Kompilation bei Änderungen)

Wie kann man zirkuläre Beziehungen auflösen und weshalb? (Beispiel mit Auto & Motor)

Mit Hilfe von Interfaces

- Auto hat noch immer einen Motor
- Auto implementiert das Interface MotorStatusListener
- Motor kennt das Auto nicht mehr, sondern nur noch Typ des Interfaces

Kein Zyklus mehr!

Welches Pattern wird in Java of für Graphical User Interfaces verwendet?

Event/Listener-Pattern

Es gibt eine Reihe von Konventionen um das Event/Listener-Pattern zu implementieren. Welches sind die zwei wesentlichsten Teile?

- Listener-Interfaces (häufig mit nur einer Methode)
- Event-Objekte (zur Zusammenfassung der relevanten Daten)

Welche Namenskonventionen für die Event-Methoden des Event/Listener-Patterns gibt es?

- Registrierung eines Listeners für einen Event (auf Quelle)
- Deregistrierung eines Listeners (auf Quelle)
- fire-Methode zur Verteilung eines Events (auf Quelle)
- listener-Methoden für Notifikation des Events (auf Empfänger)

Für was wird der PropertyChangeEvent verwendet?

Um über die Veränderung eines Properties eines Objektes zu Informieren

Was enthält der PropertyChangeEvent?

Information über die Quelle (Source), den Namen des Properties, sowie dessen alten und neuen Wert

Hinweis: Alle Event-Klassen (auch selber implementierte) werden von der Basisklasse EventObject vererbt (siehe Bild)

Welches Interface gehört zum PropertyChangeEvent und was enthält dieses Interface?

Das zum PropertyChangeEvent passende Interface für die Listener heisst PropertyChangeListener.

Es enthält eine einzige Methode: propertyChange(evt: PropertyChangeEvent){...}

Klassen, welche PropertyChangeEvents empfangen möchten, müssen welches Interface implementieren und bei der Quelle dafür registrieren?

PropertyChangeListener

Es werden (siehe Bild) drei Methoden für die Implementation einer Event-Quelle benötigt.

Was machen diese?

add... Registrierung von Listener-Objekten (public)
remove... Deregistrierung von Listener-Objekten (public)
fire... Hilfsmethode zur Versendung eines Events (private)

Zeige das Codefragment zur Implementation einer Event-Quelle

(siehe Bild)

Wie sieht das Codefragment der Klasse Motor zum Versenden eines Events?

(siehe Bild)

Wie behandelt man Events in einem Listener?
(Codebeispiel in der Klasse Car: registriert sich bei mehreren seiner Komponenten)

(siehe Bild)