2016-09-23 5 views
1

Ich bin schwer zu finden, wie Sie das Closer Dienstprogramm aus der Guava-Bibliothek verwenden. Bitte beachten Sie den folgenden Code.So verwenden Sie Guava Closer richtig

  • Eine Sache ist, dass die IndexWriter ein IOException sowohl Objektinitialisierung wirft und close(). Daher ist der Code in den End- und Wiederholungsblöcken unterstrichen.
  • Die andere Frage ist, warum habe ich Throwable statt anderen Ausnahmetypen fangen und kann ich die Fehler erneut auslösen (ich würde es vorziehen, die an der Stelle anzumelden)

`

int getDocumentsCount() { 
    Closer closer = Closer.create(); 
    try { 
     IndexWriter iwriter = closer.register(openIndexWriter()); 
     return iwriter.numDocs(); 
    } catch (Throwable e) { 
     logger.error(e, e); 
     return -1; 
    } finally { 
     closer.close(); 
    } 
} 


IndexWriter openIndexWriter() throws IOException { 
    return new IndexWriter(directory, analyzer, false, 
     IndexWriter.MaxFieldLength.UNLIMITED); 
} 

`

vielen Dank

(mit Java 6 Stück)

Antwort

4

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 Closermuss 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(); 
    } 
} 
+0

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

+0

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. –

+0

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