Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger. 
Inhaltsverzeichnis
Vorwort
1 Java ist auch eine Sprache
2 Imperative Sprachkonzepte
3 Klassen und Objekte
4 Der Umgang mit Zeichenketten
5 Eigene Klassen schreiben
6 Objektorientierte Beziehungsfragen
7 Ausnahmen müssen sein
8 Äußere.innere Klassen
9 Besondere Typen der Java SE
10 Generics<T>
11 Lambda-Ausdrücke und funktionale Programmierung
12 Architektur, Design und angewandte Objektorientierung
13 Komponenten, JavaBeans und Module
14 Die Klassenbibliothek
15 Einführung in die nebenläufige Programmierung
16 Einführung in Datenstrukturen und Algorithmen
17 Einführung in grafische Oberflächen
18 Einführung in Dateien und Datenströme
19 Einführung ins Datenbankmanagement mit JDBC
20 Einführung in <XML>
21 Testen mit JUnit
22 Bits und Bytes und Mathematisches
23 Die Werkzeuge des JDK
A Java SE-Paketübersicht
Stichwortverzeichnis


Download:

- Beispielprogramme, ca. 35,4 MB


Buch bestellen
Ihre Meinung?



Spacer
<< zurück
Java ist auch eine Insel von Christian Ullenboom

Einführung, Ausbildung, Praxis
Buch: Java ist auch eine Insel


Java ist auch eine Insel

Pfeil 7 Ausnahmen müssen sein
Pfeil 7.1 Problembereiche einzäunen
Pfeil 7.1.1 Exceptions in Java mit try und catch
Pfeil 7.1.2 Eine NumberFormatException auffangen
Pfeil 7.1.3 Eigenschaften vom Exception-Objekt
Pfeil 7.1.4 Wiederholung abgebrochener Bereiche *
Pfeil 7.1.5 Mehrere Ausnahmen auffangen
Pfeil 7.1.6 Ablauf einer Ausnahmesituation
Pfeil 7.1.7 throws im Methodenkopf angeben
Pfeil 7.1.8 Abschlussbehandlung mit finally
Pfeil 7.2 RuntimeException muss nicht aufgefangen werden
Pfeil 7.2.1 Beispiele für RuntimeException-Klassen
Pfeil 7.2.2 Kann man abfangen, muss man aber nicht
Pfeil 7.3 Die Klassenhierarchie der Fehler
Pfeil 7.3.1 Die Exception-Hierarchie
Pfeil 7.3.2 Oberausnahmen auffangen
Pfeil 7.3.3 Schon gefangen?
Pfeil 7.3.4 Alles geht als Exception durch
Pfeil 7.3.5 Zusammenfassen gleicher catch-Blöcke mit dem multi-catch
Pfeil 7.4 Harte Fehler – Error *
Pfeil 7.5 Auslösen eigener Exceptions
Pfeil 7.5.1 Mit throw Ausnahmen auslösen
Pfeil 7.5.2 Vorhandene Runtime-Fehlertypen kennen und nutzen
Pfeil 7.5.3 Parameter testen und gute Fehlermeldungen
Pfeil 7.5.4 Neue Exception-Klassen deklarieren
Pfeil 7.5.5 Eigene Ausnahmen als Unterklassen von Exception oder RuntimeException?
Pfeil 7.5.6 Ausnahmen abfangen und weiterleiten *
Pfeil 7.5.7 Aufruf-Stack von Ausnahmen verändern *
Pfeil 7.5.8 Präzises rethrow *
Pfeil 7.5.9 Geschachtelte Ausnahmen *
Pfeil 7.6 Automatisches Ressourcen-Management (try mit Ressourcen)
Pfeil 7.6.1 try mit Ressourcen
Pfeil 7.6.2 Die Schnittstelle AutoCloseable
Pfeil 7.6.3 Mehrere Ressourcen nutzen
Pfeil 7.6.4 try mit Ressourcen auf null-Ressourcen
Pfeil 7.6.5 Unterdrückte Ausnahmen *
Pfeil 7.7 Besonderheiten bei der Ausnahmebehandlung *
Pfeil 7.7.1 Rückgabewerte bei ausgelösten Ausnahmen
Pfeil 7.7.2 Ausnahmen und Rückgaben verschwinden – das Duo return und finally
Pfeil 7.7.3 throws bei überschriebenen Methoden
Pfeil 7.7.4 Nicht erreichbare catch-Klauseln
Pfeil 7.8 Den Stack-Trace erfragen *
Pfeil 7.8.1 StackTraceElement
Pfeil 7.8.2 printStackTrace(…)
Pfeil 7.8.3 StackTraceElement vom Thread erfragen
Pfeil 7.9 Assertions *
Pfeil 7.9.1 Assertions in eigenen Programmen nutzen
Pfeil 7.9.2 Assertions aktivieren
Pfeil 7.10 Zum Weiterlesen
 

Zum Seitenanfang

7.6Automatisches Ressourcen-Management (try mit Ressourcen) Zur vorigen ÜberschriftZur nächsten Überschrift

Java hat eine automatische Speicherbereinigung, die nicht mehr referenzierte Objekte erkennt und ihren Speicher automatisch freigibt. Nun bezieht sich der Garbage-Collector aber ausschließlich auf Speicher, doch es gibt viele weitere Ressourcen:

  • Dateisystemressourcen von Dateien

  • Netzwerkressourcen wie Socket-Verbindungen

  • Datenbankverbindungen

  • nativ gebundene Ressourcen vom Grafiksubsystem

  • Synchronisationsobjekte

Auch hier gilt es, nach getaner Arbeit aufzuräumen und Ressourcen freizugeben, etwa Dateien und Datenbankverbindungen zu schließen.

Mit dem try-catch-finally-Konstrukt haben wir gesehen, wie Ressourcen freizugeben sind. Doch es lässt sich auch ablesen, dass relativ viel Quellcode geschrieben werden muss und der try-catch-finally drei Unfeinheiten hat:

  1. Soll eine Variable in finally zugänglich sein, muss sie außerhalb des try-Blocks deklariert werden, was ihr eine längere Sichtbarkeit als nötig gibt.

  2. Das Schließen der Ressourcen bringt oft ein zusätzliches try-catch mit sich.

  3. Eine im finally ausgelöste Ausnahme (etwa beim close()) überdeckt die im try-Block ausgelöste Ausnahme.

 

Zum Seitenanfang

7.6.1try mit Ressourcen Zur vorigen ÜberschriftZur nächsten Überschrift

Um das Schließen von Ressourcen zu vereinfachen, gibt es eine besondere Form der try-Anweisung, die try mit Ressourcen heißt. Mit diesem Sprachkonstrukt lassen sich Ressourcentypen, die die Schnittstelle java.lang.AutoCloseable implementieren, automatisch schließen. Ein-/Ausgabeklassen wie Scanner, InputStream und Writer implementieren diese Schnittstelle und können direkt verwendet werden. Weil try mit Ressourcen dem Automatic Resource Management dient, heißt der spezielle try-Block auch ARM-Block.

Gehen wir in die Praxis: Aus einer Datei soll mit einem Scanner die erste Zeile gelesen und ausgegeben werden. Nach dem Lesen soll der Scanner geschlossen werden. Die linke Seite der folgenden Tabelle nutzt die spezielle Syntax, die rechte Seite ist im Prinzip die Übersetzung, allerdings noch etwas vereinfacht, wie wir später genauer sehen werden.

try mit Ressourcen

Vereinfachte ausgeschriebene Implementierung

InputStream in = ClassLoader.getSystemResourceAsStream( "EastOfJava.txt" );
try ( Scanner res =

new Scanner( in ) ) {
{

Scanner res =

new Scanner( in );

try {
System.out.println( res.nextLine() );
}
}

finally {

res.close();

}

}

Tabelle 7.3Die main()-Methode von TryWithResources1 und ihre prinzipielle Umsetzung

Üblicherweise folgt nach dem Schlüsselwort try ein Block, doch try mit Ressourcen nutzt eine eigene spezielle Syntax:

  1. Nach dem try folgt statt des direkten {}-Blocks eine Anweisung in runden Klammern und dann erst der {}-Block, also try () {} statt try {}.

  2. In den runden Klammern findet man eine lokale Variablendeklaration (die Variable ist automatisch final) mit einer Zuweisung. Die Ressourcenvariable muss vom Typ AutoCloseable sein. Rechts vom Gleichheitszeichen steht ein Ausdruck, etwa ein Konstruktor- oder Methodenaufruf. Der Typ des Ausdrucks muss natürlich auch intanceof AutoCloseable sein.

Die in dem try deklarierte lokale AutoCloseable-Variable ist nur in dem Block gültig und wird automatisch freigegeben, gleichgültig ob der ARM-Block korrekt durchlaufen wurde oder ob es bei der Abarbeitung zu einem Fehler kam. Der Compiler fügt alle nötigen Prüfungen ein.

[»]Hinweis

Wird auf einer Variablen, die vom Typ AutoCloseable ist, nicht close() aufgerufen oder wird sie nicht in einem try mit Ressourcen eingesetzt, gibt der Java-Compiler eine Warnung. Eclipse etwa meldet: »Resource leak: '<unassigned Closeable value>' is never closed«. Die Warnung verschwindet mit @SuppressWarnings("resource").

Ausnahmen vom close() bleiben bestehen

Unser Scanner-Beispiel hat eine Besonderheit, denn keine der Methoden löst eine geprüfte Ausnahme aus – weder getSystemResourceAsStream(…), new Scanner(InputStream), nextLine() noch das close(), das try mit Ressourcen automatisch aufruft. Anders ist es, wenn die Ressource ein klassischer Datenstrom (InputStream/OutputStream/Reader/Writer) ist, denn dort deklariert die close()-Methode eine IOException. Die muss daher auch behandelt werden, wie es das folgende Beispiel zeigt:

Listing 7.25TryWithResourcesReadsLine, readFirstLine()

static String readFirstLine( String file ) {

try ( BufferedReader br = Files.newBufferedReader(

Paths.get( file ), StandardCharsets.ISO_8859_1 ) ) {

return br.readLine();

}

catch ( IOException e ) { e.printStackTrace(); return null; }

}

Wenn try mit Ressourcen verwendet wird, bleibt die deklarierte Ausnahme bei close() bestehen; es zaubert die in der Regel ausgelöste IOException nicht weg, und entweder muss ein fangendes catch her oder die Ausnahme weitergeleitet werden. Daraus ergibt sich ein interessanter Nebeneffekt: Hat ein Aufruf von einem IOException-auslösenden close() im Code gefehlt und wird Programmcode in der try-mit-Ressoucen-Syntax umgeschrieben, so führt der vom Compiler automatisch eingesetzte close()-Aufruf zu einem Compilerfehler, wenn die geprüfte IOException nicht behandelt wird.

[»]Hinweis

Löst close() eine geprüfte Ausnahme aus und wird diese nicht behandelt, so kommt es zum Compilerfehler. Die close()-Methode vom BufferedReader löst zum Beispiel eine IOException aus, sodass sich die folgende Methode nicht übersetzen lässt:

void no() {

try ( Reader r = new BufferedReader(null) ) { } // inline Compilerfehler

}

Der Ausdruck new BufferedReader(null) benötigt keine Behandlung, denn der Konstruktor löst keine Ausnahme aus. Einzig der nicht behandelte Fehler von close() führt zu »exception thrown from implicit call to close() on resource variable 'r'«.

 

Zum Seitenanfang

7.6.2Die Schnittstelle AutoCloseable Zur vorigen ÜberschriftZur nächsten Überschrift

Die ARM-Anweisung schließt Ressourcen vom Typ AutoCloseable. Daher wird es Zeit, sich diese Schnittstelle etwas genauer anzuschauen:

Listing 7.26java/lang/AutoCloseable.java

package java.lang;



public interface AutoCloseable {

void close() throws Exception;

}

Anders als das übliche close() ist die Ausnahme deutlich allgemeiner mit Exception angegeben; die Ein-/Ausgabe-Klassen lösen beim Misslingen immer eine IOException aus, aber jede Klasse hat eigene Ausnahmetypen:

Typ

Signatur

java.io.Scanner

close() // ohne Ausnahme

javax.sound.sampled.Line

close() // ohne Ausnahme

java.io.FileInputStream

close() throws IOException

java.sql.Connection

close() throws SQLException

Tabelle 7.4Einige Typen, die AutoCloseable implementieren

Eine Unterklasse darf die Ausnahme ja auch weglassen; das machen Klassen wie der Scanner, der keine Ausnahme weiterleitet, sondern sie intern schluckt – wenn es Ausnahmen gab, liefert sie die Scanner-Methode ioException().

AutoCloseable und Closeable

Auf den ersten Blick einleuchtend wäre es, die schon existierende Schnittstelle Closeable als Typ zu nutzen. Doch das hätte Nachteile: Die close()-Methode ist mit einem throws IOException deklariert, was bei einer allgemeinen automatischen Ressourcenfreigabe unpassend ist, wenn etwa ein Grafikobjekt bei der Freigabe eine IOException auslöst. Vielmehr ist der Weg andersherum: Closeable erweitert AutoCloseable, denn das Schließen von Ein-/Ausgabe-Ressourcen ist eine besondere Art, allgemeine Ressourcen zu schließen.

package java.io;



import java.io.IOException;



public interface Closeable extends AutoCloseable {

void close() throws IOException;

}

Wer ist AutoCloseable?

Da alle Klassen, die Closeable implementieren, auch automatisch vom Typ AutoCloseable sind, kommen schon einige Typen zusammen. Im Wesentlichen sind es aber Klassen aus dem java.io-Paket, wie Channel-, Reader-, Writer-Implementierungen, FileLock, XMLDecoder und noch ein paar Exoten wie URLClassLoader, ImageOutputStream. Auch Typen aus dem java.sql-Paket gehören zu den Nutznießern. Klassen aus dem Bereich Threading, wo etwa ein Lock wieder freigegeben werden könnte, oder Grafikanwendungen, bei denen der Grafikkontext wieder freigegeben werden muss, gehören nicht dazu.

[»]Hinweis

Es gibt Ströme, die müssen offen bleiben. Das gilt etwa für System.in, einen vom System bereitgestellten InputStream. Auch wenn dieser in einem Scanner verpackt wird, wird ein close() auf dem Scanner zu einem close() auf dem InputStream, und ein erneutes Lesen aus System.in wird mit einem »java.io.IOException: Stream closed« quittiert. Ein try ( Scanner in = new Scanner(System.in) ) { } ist also keine gute Idee.

[+]Tipp *

Es ist mit einem Trick möglich, auch Exemplare in einem try mit Ressourcen zu nutzen, die nicht vom Typ AutoCloseable sind. Ein Lambda-Ausdruck oder eine Methodenreferenz lassen sich nutzen, um eine beliebige Methode als close()-Methode einzusetzen. Ein ReentrantLock zum Beispiel ist eine Implementierung eines Lock, um bei nebenläufigen Zugriffen einen Bereich abzuschließen. lock() beginnt den Bereich, unlock() gibt ihn wieder frei. Das unlock() lässt sich über einen Lambda-Ausdruck als close()-Methode verkaufen.

ReentrantLock lock = new ReentrantLock();

try ( AutoCloseable unlock = lock::unlock ) { // oder () -> {lock.unlock();}

lock.lock();

}

System.out.println( lock.isLocked() ); // false

Ob dieser »Trick« sinnvoll ist oder nicht, ist eine andere Frage. Das try mit Ressourcen setzt auf jeden Fall das unlock() in einen internen finally-Block, der über die Konstruktion eingespart wird. Allerdings wird üblicherweise die Ressource im try-mit-Ressourcen-Block auch erst deklariert, was hier vorher gemacht werden muss, außerdem ist die Variable unlock unnütz. Daher ist die Relevanz eher niedrig.

 

Zum Seitenanfang

7.6.3Mehrere Ressourcen nutzen Zur vorigen ÜberschriftZur nächsten Überschrift

Unsere beiden Beispiele zeigen die Nutzung eines Ressourcentyps. Es sind aber auch mehrere Typen möglich, die ein Semikolon trennt:

try ( InputStream in = Files.newInputStream( srcPath );

OutputStream out = Files.newOutputStream( destPath ) ) {

...

}

[»]Hinweis

Die Trennung erledigt ein Semikolon, und jedes Segment kann einen unterschiedlichen Typ deklarieren, etwa InputStream/OutputStream. Die Ressourcentypen müssen also nicht gleich sein, und auch wenn sie es sind, muss der Typ immer neu geschrieben werden, also etwa:

try ( InputStream in1 = ...; InputStream in2 = ... )

Es ist ungültig, Folgendes zu schreiben:

try ( InputStream in1 = ..., in2 = ... ) // inline Compilerfehler

Wenn es beim Anlegen in der Kette zu einem Fehler kommt, wird nur das geschlossen, was auch aufgemacht wurde. Wenn es also bei der ersten Initialisierung von in1 schon zu einer Ausnahme kommt, wird die Belegung von in2 erst gar nicht begonnen und daher auch nicht geschlossen. (Intern setzt der Compiler das als geschachtelte try-catch-finally-Blöcke um.)

[zB]Beispiel

Am Schluss der Ressourcensammlung kann – muss aber nicht – ein Semikolon stehen, so wie auch bei Array-Initialisierungen zum Schluss ein Komma stehen kann:

int[] array = { 1, 2, };

// ^ Komma optional

try ( InputStream in = Files.newInputStream( path ); ) { ... }

// ^ Semikolon optional

try ( InputStream in = Files.newFileInputStream( src );

OutputStream out = Files.newOutputStream( dest ); ) { ... }

// ^ Semikolon optional

Ob das stilvoll ist, muss jeder selbst entscheiden; in der Insel steht kein unnützes Zeichen.

 

Zum Seitenanfang

7.6.4try mit Ressourcen auf null-Ressourcen Zur vorigen ÜberschriftZur nächsten Überschrift

Dass immer zum Abschluss eines try-mit-Ressourcen-Blocks ein close() aufgerufen wird, ist nicht ganz korrekt; es gibt nur dann einen Schließversuch, wenn die Ressource ungleich null ist.

[zB]Beispiel

Der Codebaustein compiliert und führt zu einer Konsolenausgabe:

try ( Scanner scanner1 = null; Scanner scanner2 = null ) {

System.out.println( "Ok" );

}

Bei Konstruktoren ist ein Objekt ja immer gegeben, aber es gibt auch Fabrikaufrufe, bei denen vielleicht null herauskommen kann, und für diese Fälle ist es ganz praktisch, dass try mit Ressourcen dann nichts macht, um eine NullPointerException beim close() zu vermeiden.

 

Zum Seitenanfang

7.6.5Unterdrückte Ausnahmen * Zur vorigen ÜberschriftZur nächsten Überschrift

Aufmerksame Leser haben bestimmt schon ein Detail wahrgenommen: Im Text steht »vereinfachte ausgeschriebene Implementierung«, was vermuten lässt, dass es ganz so einfach doch nicht ist. Das stimmt, denn es können zwei Ausnahmen auftauchen, die einiges an Sonderbehandlung benötigen:

  • Ausnahme im try-Block, an sich unproblematisch

  • Ausnahme beim close(), auch an sich unproblematisch. Aber es gibt mehrere close()-Aufrufe, wenn nicht nur eine Ressource verwendet wurde. Ungünstig.

  • Die Steigerung: Ausnahme im try-Block und dann auch noch Ausnahme(n) beim close(). Das ist ein echtes Problem!

Eine Ausnahme allein ist kein Problem, aber zwei Ausnahmen auf einmal bilden ein großes Problem, da ein Programmblock nur genau eine Ausnahme melden kann und nicht eine Sequenz von Ausnahmen. Daher sind verschiedene Fragen zu klären, falls der try-Block und close() beide eine Ausnahme auslösen:

  • Welche Ausnahme ist wichtiger? Die Ausnahme im try-Block oder die vom close()?

  • Wenn es zu zwei Ausnahmen kommt: Soll die von close() vielleicht immer verdeckt werden und immer nur die vom try-Block zum Anwender kommen?

  • Wenn beide Ausnahmen gleich wichtig sind, wie sollen sie gemeldet werden?

Wie haben sich die Java-Ingenieure entschieden? Eine Ausnahme bei close() darf bei einem gleichzeitigen Auftreten einer Exception im try-Block auf keinen Fall verschwinden.[ 183 ](In einem frühen Prototyp war dies tatsächlich der Fall – die Ausnahme wurde komplett geschluckt. ) Wie also beide Ausnahmen melden? Hier gibt es einen Trick: Da die Ausnahme im try-Block wichtiger ist, ist sie die »Haupt-Ausnahme«, und die close()-Ausnahme kommt Huckepack als Extra-Information mit obendrauf.

Dieses Verhalten soll das nächste Beispiel zeigen. Um die Ausnahmen besser steuern zu können, soll eine eigene AutoCloseable-Implementierung eine Ausnahme in close() auslösen.

Listing 7.27NotCloseable.java

public class NotCloseable implements AutoCloseable {

@Override public void close() {

throw new UnsupportedOperationException( "close() mag ich nicht" ); // inline

}

}

Zum Beispiel selbst:

Listing 7.28SuppressedClosed.java

public class SuppressedClosed {

public static void main( String[] args ) {

try ( NotCloseable res = new NotCloseable() ) {

throw new NullPointerException(); // inline

}

}

}

Das Programm löst also im close() und im try-Block eine Ausnahme aus. Das Resultat ist:

Exception in thread "main" java.lang.NullPointerException

at SuppressedClosed.main(SuppressedClosed.java:4)

Suppressed: java.lang.UnsupportedOperationException: close() mag ich nicht

at NotCloseable.close(NotCloseable.java:3)

at SuppressedClosed.main(SuppressedClosed.java:5)

Die interessante Zeile beginnt mit Suppressed:, denn dort ist die close()-Ausnahme referenziert. An den Aufrufer kommt die spannende Ausnahme vom misslungenen try-Block aber nicht direkt von close(), sondern verpackt in der Hauptausnahme und muss extra erfragt werden.

Zum Vergleich: Kommentieren wir throw new NullPointerException() aus, gibt es nur noch die close()-Ausnahme, und es folgt auf der Konsole:

Exception in thread "main" java.lang.UnsupportedOperationException: close() mag ich

nicht

at SuppressedClosed$1NotCloseable.close(SuppressedClosed.java:3)

at SuppressedClosed.main(SuppressedClosed.java:5)

Die Ausnahme ist also nicht irgendwo anders untergebracht, sondern die »Hauptausnahme«.

Eine Steigerung ist, dass es mehr als eine Ausnahme beim Schließen geben kann. Simulieren wir auch dies wieder an einem Beispiel, indem wir unser Beispiel um eine Zeile ergänzen:

Listing 7.29SuppressedClosed2.java

try ( NotCloseable res1 = new NotCloseable();

NotCloseable res2 = new NotCloseable() ) {

throw new NullPointerException();

}

Aufgerufen führt dies zu:

Exception in thread "main" java.lang.NullPointerException

at SuppressedClosed.main(SuppressedClosed.java:5)

Suppressed: java.lang.UnsupportedOperationException: close() mag ich nicht

at SuppressedClosed$1NotCloseable.close(SuppressedClosed.java:3)

at SuppressedClosed.main(SuppressedClosed.java:6)

Suppressed: java.lang.UnsupportedOperationException: close() mag ich nicht

at SuppressedClosed$1NotCloseable.close(SuppressedClosed.java:3)

at SuppressedClosed.main(SuppressedClosed.java:6)

Jede unterdrückte close()-Ausnahme taucht auf.

Umsetzung

In Abschnitt 7.1.8, »Abschlussbehandlung mit finally«, wurde das Verhalten vorgestellt, dass eine Ausnahme im finally eine Ausnahme im try-Block unterdrückt. Der Compiler setzt bei der Umsetzung vom try mit Ressourcen das close() in einen finally-Block. Ausnahmen im finally-Block sollen eine mögliche Hauptausnahme aber nicht schlucken. Daher fängt die Umsetzung vom Compiler jede mögliche Ausnahme im try-Block ab sowie die close()-Ausnahme und hängt diese Schließ-Ausnahme, falls vorhanden, an die Hauptausnahme.

Spezielle Methoden in Throwable *

Damit eine normale Exception die unterdrückten close()-Ausnahmen Huckepack nehmen kann, gibt es in der Basisklasse Throwable zwei besondere Methoden:

final class java.lang.Throwable
  • final Throwable[] getSuppressed()

    Liefert alle unterdrückten Ausnahmen. Die printStackTrace(…)-Methode zeigt alle unterdrückten Ausnahmen und greift auf getSuppressed() zurück. Für Anwender wird es selten Anwendungsfälle für diese Methode geben.

  • final void addSuppressed(Throwable exception)

    Fügt eine neue unterdrückte Ausnahme hinzu. In der Regel ruft der finally-Block vom try mit Ressourcen die Methode auf, doch wir können auch selbst die Methode nutzen, wenn wir mehr als eine Ausnahme melden wollen. Die Java-Bibliothek selbst nutzt das bisher nur an sehr wenigen Stellen.

Neben den beiden Methoden gibt es einen protected-Konstruktor, der bestimmt, ob es überhaupt unterdrückte Ausnahmen geben soll oder ob sie nicht vielleicht komplett geschluckt werden. Wenn, dann zeigt sie auch printStackTrace(…) nicht mehr an.

Blick über den Tellerrand

In C++ gibt es Dekonstruktoren, die beliebige Anweisungen ausführen, wenn ein Objekt freigegeben wird. Hier lässt sich auch das Schließen von Ressourcen realisieren. C# nutzt statt try das spezielle Schlüsselwort using, mit Typen, die die Schnittstelle IDisposable implementieren, mit einer Methode Dispose() statt close() (in Java sollte die Schnittstelle ursprünglich auch Disposable statt nun AutoCloseable heißen). In Python 2.5 wurde ein context management protocol mit dem Schlüsselwort with realisiert, sodass Python automatisch bei Betreten eines Blocks __enter__() aufruft und beim Verlassen die Methode __exit__(). Das ist insofern interessant, als hier zwei Methoden zur Verfügung stehen. Bei Java ist es nur close() beim Verlassen des Blocks, aber es gibt keine Methode zum Betreten eines Blocks; so etwas muss beim Anlegen der Ressource erledigt werden.

 


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.

>> Zum Feedback-Formular
<< zurück

 

 


Copyright © Rheinwerk Verlag GmbH 2017

Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.

 

[Rheinwerk Computing]



Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de