Angenommen, ich habe eine Klasse und eine Methode
class A {
void foo() throws Exception() {
...
}
}
Jetzt möchte ich foo für jede A
von einem Stream gelieferte Instanz aufrufen wie:
void bar() throws Exception {
Stream<A> as = ...
as.forEach(a -> a.foo());
}
Frage: Wie gehe ich mit der Ausnahme richtig um? Der Code wird auf meinem Computer nicht kompiliert, da ich die möglichen Ausnahmen, die von foo () ausgelöst werden können, nicht behandle. Das throws Exception
von bar
scheint hier nutzlos zu sein. Warum ist das so?
java
java-8
unhandled-exception
java-stream
Bastian
quelle
quelle
Antworten:
Sie müssen Ihren Methodenaufruf in einen anderen umschließen, in dem Sie keine aktivierten Ausnahmen auslösen . Sie können immer noch alles werfen, was eine Unterklasse von ist
RuntimeException
.Eine normale Verpackungssprache ist so etwas wie:
(Die Supertyp-Ausnahme
Exception
wird nur als Beispiel verwendet. Versuchen Sie niemals, sie selbst abzufangen.)Dann können Sie es aufrufen mit :
as.forEach(this::safeFoo)
.quelle
Wenn Sie nur aufrufen möchten
foo
und die Ausnahme lieberfor
unverändert weitergeben möchten (ohne Umbruch), können Sie stattdessen auch einfach die Java- Schleife verwenden (nachdem Sie den Stream mit einigen Tricks in eine Iterable verwandelt haben ):Dies ist zumindest das, was ich in meinen JUnit-Tests mache, in denen ich nicht die Mühe machen möchte, meine geprüften Ausnahmen zu verpacken (und meine Tests tatsächlich den nicht verpackten Originalausnahmen vorzuziehen).
quelle
Diese Frage mag etwas alt sein, aber weil ich denke, dass die "richtige" Antwort hier nur eine Möglichkeit ist, die später in Ihrem Code zu versteckten Problemen führen kann. Auch wenn es ein wenig kontrovers ist , gibt es aus einem bestimmten Grund geprüfte Ausnahmen.
Der meiner Meinung nach eleganteste Weg, den Sie finden können, wurde von Misha hier angegeben. Aggregieren Sie Laufzeitausnahmen in Java 8-Streams, indem Sie nur die Aktionen in "Futures" ausführen. So können Sie alle Arbeitsteile ausführen und nicht funktionierende Ausnahmen als eine einzige sammeln. Andernfalls könnten Sie sie alle in einer Liste sammeln und später verarbeiten.
Ein ähnlicher Ansatz stammt von Benji Weber . Er schlägt vor, einen eigenen Typ zu erstellen, um funktionierende und nicht funktionierende Teile zu sammeln.
Je nachdem, was Sie wirklich erreichen möchten, erfolgt eine einfache Zuordnung zwischen den Eingabewerten und den aufgetretenen Ausgabewerten. Ausnahmen können auch für Sie funktionieren.
Wenn Ihnen eine dieser Möglichkeiten nicht gefällt, sollten Sie (abhängig von der ursprünglichen Ausnahme) mindestens eine eigene Ausnahme verwenden.
quelle
stream.map(Streams.passException(x->mightThrowException(x))).catch(e->whatToDo(e)).collect(...)
. Es sollte Ausnahmen erwarten und es Ihnen ermöglichen, sie wie Futures zu behandeln.Ich schlage vor, die Google Guava Throwables-Klasse zu verwenden
AKTUALISIEREN:
Jetzt, da es veraltet ist, verwenden Sie:
quelle
Auf diese Weise können Sie Ausnahmen ein- und auspacken.
quelle
Möglicherweise möchten Sie einen der folgenden Schritte ausführen:
In mehreren Bibliotheken können Sie dies problemlos tun. Das folgende Beispiel wurde mit meiner NoException- Bibliothek geschrieben.
quelle
Besser lesbarer Weg:
Verstecke es einfach in einem
RuntimeException
, um es vorbei zu bringenforEach()
Obwohl ich mich an dieser Stelle nicht gegen jemanden behaupten werde, wenn er sagt, überspringe die Streams und gehe mit einer for-Schleife, es sei denn:
Collection.stream()
, dh nicht mit einer einfachen Übersetzung in eine for-Schleife.parallelstream()
quelle