Wie wird die IOException in Iterable.forEach behandelt?

8

Ich spiele mit Möglichkeiten, eine Reihe von Objekten in eine Datei zu schreiben. Warum kompiliert die folgende Implementierung, die Iterable.forEach () verwendet, nicht? In Eclipse bekomme ich die Nachricht, dass eine IOException nicht behandelt wird. Dies ist besonders verwirrend, da ich anscheinend IOExceptions verarbeitet.

%Vor%

Offensichtlich funktioniert das unten. Ich bin daran interessiert, warum das oben genannte nicht funktioniert und wie man es repariert.

%Vor%

Ich habe den Verbraucher und Iterable Dokumentation, und keiner von ihnen scheint darauf hinzuweisen, wie man das löst.

    
Will Beason 24.04.2015, 19:41
quelle

4 Antworten

9

Precursor: Die Anforderung zum Abfangen oder Angeben .

Lassen Sie uns das Lambda als anonyme Klasse schreiben:

%Vor%

Gehen wir damit um? Es sollte klar sein, dass wir es nicht sind.

Wenn wir einen Lambda-Ausdruck schreiben, deklarieren wir den Körper einer Methode. Wir können auch keine throws -Klausel für ein Lambda deklarieren.

Der einzige "Weg" wäre, etwas wie das Folgende zu tun:

%Vor%

Aber das ist wirklich nicht gut.

Verwenden Sie stattdessen nicht forEach in einem Kontext, der eine geprüfte Ausnahme auslöst, oder fangen Sie die Ausnahme im Hauptteil des Lambda ab.

    
Radiodef 24.04.2015, 19:54
quelle
6

Wenn Sie nur daran interessiert sind, Zeichenketten in eine Datei zu drucken, verwenden Sie PrintStream oder vielleicht PrintWriter anstelle der anderen Writer -Klassen. Das bemerkenswerte Feature von PrintStream und PrintWriter ist, dass ihre Druckvorgänge nicht IOException auslösen. Sie rufen auch toString für Objekte automatisch auf, was die Dinge sehr praktisch macht:

%Vor%

Wenn Sie über Fehler besorgt sind, können Sie PrintStream.checkError aufrufen, obwohl dies keine Einzelheiten zu einem eventuell aufgetretenen Fehler enthält.

Die allgemeine Frage steht immer noch, was zu tun ist, wenn Sie eine ausnahmegestützende Methode innerhalb eines Kontexts (wie forEach ) aufrufen möchten, der dies nicht zulässt. Das ist nur lästig, wenn auch nur mäßig. Es erfordert jedoch einige Einstellungen. Angenommen, wir möchten ein Consumer schreiben, das ein IOException wirft. Wir müssen eine eigene funktionale Schnittstelle deklarieren:

%Vor%

Jetzt müssen wir eine Funktion schreiben, die ein IOConsumer in ein Consumer umwandelt. Dazu konvertiert sie IOException in eine UncheckedIOException , eine Ausnahme, die für diesen Zweck erstellt wurde.

%Vor%

Wenn diese vorhanden sind, können wir das ursprüngliche Beispiel wie folgt umschreiben:

%Vor%     
Stuart Marks 25.04.2015 06:46
quelle
2

Das Problem ist, dass die Methode accept in der Schnittstelle Consumer nicht zum Auslösen einer Ausnahme deklariert ist. Daher können Sie keine Methode verwenden, die eine geprüfte Ausnahme in Lambda wirft.

Die Lösung besteht darin, stattdessen einen für jede Schleife zu verwenden.

    
Paul Boddington 24.04.2015 19:50
quelle
1

Normalerweise schreiben wir keine Daten in die Datei, wenn eine Ausnahme auftritt. In diesem Sinne können wir unsere own consumer which will wrap the checked exception into an unchecked exception schreiben. Auf diese Weise könnten Sie mit dem Kompilierzeitfehler davonkommen. Bitte versuchen Sie es unter dem folgenden Code

%Vor%     
Shirishkumar Bari 25.04.2015 11:02
quelle