Von Guava's own explanation, haben Sie haben zu verwenden Throwable
, ja.
Hier ist ihr Beispiel Schnipsel:
public void foo() throws IOException {
Closer closer = Closer.create();
try {
InputStream in = closer.register(openInputStream());
OutputStream out = closer.register(openOutputStream());
// do stuff with in and out
} catch (Throwable e) { // must catch Throwable
throw closer.rethrow(e);
} finally {
closer.close();
}
}
anzumerken, dass sie fangen Throwable
und rethrow es direkt aus der Closer
Instanz.
Wie, warum es ist Throwable
und nicht, sagen wir mal IOException
oder RuntimeException
, es ist, weil die Closer
muss wissen, dass ein Fehler aufgetreten ist, so dass es richtig die Ressourcen schließen kann. Alles ist nur eine Frage der richtigen Dinge. Es kann also funktionieren, wenn Sie es nicht richtig machen, aber es ist nicht garantiert.
Nicht, dass, wenn Ihre Methode MyOwnCheckedException
zum Beispiel werfen kann, Sie haben sie erklären:
} catch (Throwable t) {
throw closer.rethrow(e, MyOwnCheckedException.class);
} finally {
closer.close();
}
Java 7 Beispiel zum Vergleich:
public void foo() throws IOException {
try (InputStream in = openInputStream();
OutputStream out = openOutputStream();
// do stuff with in and out
}
}
Wenn Sie die Closer
vergleichen Beispiel mit dem Java 7-Beispiel, Sie sehen, dass ich immer noch die IOException
in der Methodensignatur deklarieren muss.
Für Ihren Fall ist es das, was Sie tun müssen:
int getDocumentsCount() {
try {
Closer closer = Closer.create();
try {
IndexWriter iwriter = closer.register(openIndexWriter());
return iwriter.numDocs();
} catch (Throwable e) {
closer.rethrow(e);
} finally {
closer.close();
}
} catch (IOException e) {
logger.error(e, e);
return -1;
}
}
Try-Pyramiden zu vermeiden, würde ich folgendes tun:
int getDocumentsCount() {
try {
return doGetDocumentsCount();
} catch (IOException e) {
logger.error(e, e);
return -1;
}
}
int doGetDocumentsCount() throws IOException {
Closer closer = Closer.create();
try {
IndexWriter iwriter = closer.register(openIndexWriter());
return iwriter.numDocs();
} catch (Throwable e) {
closer.rethrow(e);
} finally {
closer.close();
}
}
1) Ich habe habe auch ihr Beispiel gesehen. Das Problem ist, dass ich einen Kompilierungsfehler im finally-Block bekomme, weil der nähere "IOException" werfen kann. 2) Muss ich die Ausnahme erneut auslösen? Ich meine, ich sehe nicht, wie es dem Closer hilft, die Ausnahme zu registrieren. Es ist schließlich der näher, der die Ausnahme, die im Catch-Block gefangen ist (die es eigentlich schon bewusst ist), erneut ausliest. – d56
Nein, Sie müssen die Ausnahme nicht erneut auslösen: Sie müssen es ** deklarieren **. Ich habe die Antwort angepasst, um zu zeigen, dass Sie die IOException deklarieren müssen. Beachten Sie, dass "Closer" nur das Schließen von 'Closeable' behandelt. Es sagt nichts darüber aus, wie die Ausnahme außerhalb des Bereichs "Closer" gehandhabt wird. –
Danke. 1) Aber ich möchte nicht die 'IOException' überhaupt werfen, es ist etwas irritierend, dass der 'Closer' nicht damit umgehen kann und zwingt mich, es in der Methodensignatur zu deklarieren. 2) Was ich auch nicht verstehe ist, warum ich "MyOwnCheckedException" erneut versuchen muss? Ist es nur eine Möglichkeit, die von der Ressource ausgelöste Ausnahme in meine eigene zu konvertieren? – d56