Ich bin gerade dabei, Java zu lernen und kann keine gute Erklärung für das implements Closeable
und das findenimplements AutoCloseable
Schnittstellen finden.
Bei der Implementierung von interface Closeable
hat meine Eclipse-IDE eine Methode erstellt public void close() throws IOException
.
Ich kann den Stream pw.close();
ohne die Schnittstelle schließen. Aber ich kann nicht verstehen, wie ich das implementieren kannclose()
Methode über die Schnittstelle . Und was ist der Zweck dieser Schnittstelle?
Außerdem würde ich gerne wissen: Wie kann ich überprüfen, ob IOstream
wirklich geschlossen wurde?
Ich habe den folgenden Basiscode verwendet
import java.io.*;
public class IOtest implements AutoCloseable {
public static void main(String[] args) throws IOException {
File file = new File("C:\\test.txt");
PrintWriter pw = new PrintWriter(file);
System.out.println("file has been created");
pw.println("file has been created");
}
@Override
public void close() throws IOException {
}
Antworten:
Es scheint mir, dass Sie mit Schnittstellen nicht sehr vertraut sind. In dem Code, den Sie gepostet haben, müssen Sie nicht implementieren
AutoCloseable
.Sie müssen (oder sollten) nur implementieren
Closeable
oderAutoCloseable
wenn Sie im Begriff sind, Ihre eigenen zu implementierenPrintWriter
, die Dateien oder andere Ressourcen verarbeiten, die geschlossen werden müssen.In Ihrer Implementierung reicht es aus, aufzurufen
pw.close()
. Sie sollten dies in einem finally-Block tun:Der obige Code bezieht sich auf Java 6. In Java 7 kann dies eleganter erfolgen (siehe diese Antwort ).
quelle
PrintWriter
? InsbesondereAutoClosable
Objekte können unter viel mehr Umständen als nurPrintWriter
...PrintWriter
so, dass ich sie genauer erwähnte.AutoCloseable
? Zeigen Sie liebertry-with-resources
stattdessen ...AutoCloseable
(eingeführt in Java 7) ermöglicht die Verwendung des Try-with-Resources- Idioms:Jetzt können Sie sagen:
und JVM ruft
close()
automatisch für Sie an.Closeable
ist eine ältere Schnittstelle.Aus irgendeinem GrundUm die Abwärtskompatibilität zu gewährleisten, haben Sprachdesigner beschlossen, eine separate zu erstellen. Dies ermöglicht nicht nur die Verwendung allerCloseable
Klassen (wie das Auslösen von StreamsIOException
) beim Ausprobieren von Ressourcen, sondern auch das Auslösen allgemeinerer geprüfter Ausnahmen vonclose()
.Im Zweifelsfall sind
AutoCloseable
Benutzer Ihrer Klasse dankbar.quelle
Closeable.close()
WürfeIOException
. Vieleclose()
Methoden , die von Try-mit-Ressourcen werfen andere geprüfte Ausnahmen profitieren könnten (zBjava.sql.Connection.close()
soAutoCloseable.close()
wirftException
den bestehenden ändern.Closeable
Vertrag alle bestehenden Anwendungen brechen würde / Bibliothek auf dem Vertrag zu verlassen , dassclose()
nur wirftIOException
und nicht alle (markiert) Ausnahmen.Closeable.close()
muss idempotent sein.AutoCloseable.close()
ist nicht, obwohl es immer noch dringend empfohlen wird.public void close( ) throws Exception
- verwenden Sie eine spezifischere Ausnahme, wenn Sie können (z. B. IOException)Closeable
garantiert keine Idempotenz. Es erfordert Idempotenz bei der Implementierung derclose()
Methode durch einen Benutzer . Und ob diesIOException
spezifischer / angemessener ist, hängt vom Anwendungsfall ab.Closeable
erweitertAutoCloseable
und ist speziell für E / A-Streams vorgesehen: Es löst IOException anstelle von Exception aus und ist idempotent, während AutoCloseable diese Garantie nicht bietet.Dies alles wird im Javadoc beider Schnittstellen erklärt.
Durch die Implementierung von AutoCloseable (oder Closeable) kann eine Klasse als Ressource des in Java 7 eingeführten Try-with-Resources-Konstrukts verwendet werden, mit dem solche Ressourcen am Ende eines Blocks automatisch geschlossen werden können, ohne dass ein abschließender Block hinzugefügt werden muss, der geschlossen wird die Ressource explizit.
Ihre Klasse stellt keine verschließbare Ressource dar, und es macht absolut keinen Sinn, diese Schnittstelle zu implementieren: Ein IOTest kann nicht geschlossen werden. Es sollte nicht einmal möglich sein, es zu instanziieren, da es keine Instanzmethode gibt. Denken Sie daran, dass die Implementierung einer Schnittstelle bedeutet, dass es eine gibt zwischen der Klasse und der Schnittstelle eine Beziehung besteht. Sie haben hier keine solche Beziehung.
quelle
Hier ist das kleine Beispiel
Hier ist die Ausgabe:
quelle
this.close()
oder etwas im Code sein?, Weil es automatisch aufgerufen wird (nur um sicher zu sein)Die
try-with-resources
Aussage.Dies
try-with-resources statement
ist einetry
Anweisung, die eine oder mehrere Ressourcen deklariert. Aresource
ist ein Objekt, das geschlossen werden muss, nachdem das Programm damit beendet wurde. Dastry-with-resources statement
stellt sicher , dass jede Ressource an dem Ende der Anweisung geschlossen ist. Jedes implementierte Objekt,java.lang.AutoCloseable
einschließlich aller implementierten Objektejava.io.Closeable
, kann als Ressource verwendet werden.Das folgende Beispiel liest die erste Zeile aus einer Datei. Es verwendet eine Instanz von
BufferedReader
, um Daten aus der Datei zu lesen.BufferedReader
ist eine Ressource, die geschlossen werden muss, nachdem das Programm damit beendet wurde:In diesem Beispiel ist die in der Anweisung try-with-resources deklarierte Ressource ein BufferedReader. Die Deklarationsanweisung wird unmittelbar nach dem Schlüsselwort try in Klammern angezeigt. Die Klasse
BufferedReader
implementiert in Java SE 7 und höher die Schnittstellejava.lang.AutoCloseable
. Da dieBufferedReader
Instanz in einer try-with-resource-Anweisung deklariert ist, wird sie geschlossen, unabhängig davon, ob die try-Anweisung normal oder abrupt ausgeführt wird (aufgrund der MethodeBufferedReader.readLine
, die eine auslöstIOException
).Vor Java SE 7 können Sie mithilfe eines
finally
Blocks sicherstellen, dass eine Ressource geschlossen wird, unabhängig davon, ob die try-Anweisung normal oder abrupt ausgeführt wird. Im folgenden Beispiel wird einfinally
Block anstelle einertry-with-resources
Anweisung verwendet:Bitte beachten Sie die Dokumente .
quelle
Kürzlich habe ich ein Java SE 8 Programmer Guide ii Book gelesen.
Ich habe etwas über den Unterschied zwischen
AutoCloseable
vs gefundenCloseable
.Die
AutoCloseable
Schnittstelle wurde in Java 7 eingeführt. Davor gab es eine andere Schnittstelle namensCloseable
. Es war ähnlich wie das, was die Sprachdesigner wollten, mit den folgenden Ausnahmen:Closeable
schränkt die Art der ausgelösten Ausnahme einIOException
.Closeable
erfordert, dass Implementierungen idempotent sind.Die Sprachdesigner legen Wert auf Abwärtskompatibilität. Da das Ändern der vorhandenen Schnittstelle unerwünscht war, wurde eine neue aufgerufen
AutoCloseable
. Diese neue Schnittstelle ist weniger streng alsCloseable
. Da esCloseable
die Anforderungen für erfülltAutoCloseable
, begann es mit der Implementierung,AutoCloseable
als letzteres eingeführt wurde.quelle
Closeable
", würde ich vorschlagen, dass "Diese neue Schnittstelle kann in allgemeineren Kontexten verwendet werden, in denen die beim Schließen ausgelöste Ausnahme nicht unbedingt eine IOException ist". Im Java-Universum hat "weniger streng" eine negative Stimmung.