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.
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.
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:
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:
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.
Wenn diese vorhanden sind, können wir das ursprüngliche Beispiel wie folgt umschreiben:
%Vor% 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.
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
Tags und Links java java-8 lambda foreach checked-exceptions