Java 8 Lambda-Funktion throws exception?
Weiß ich, wie man erstellen Sie einen Verweis auf eine Methode, die eine String
parameter und gibt int
:
Function<String, Integer>
Aber das funktioniert nicht, wenn die Funktion eine exception wirft, sagen, es ist definiert als:
Integer myMethod(String s) throws IOException
Wie würde ich das definieren dieser Referenz?
Verwandte: stackoverflow.com/questions/31637892/...
...und diese hier: stackoverflow.com/questions/31270759/...
github.com/TouK/ThrowingFunction
Die Lösung sieht wie einige, werfen Runtime-Ausnahmen, ich glaube es ist keine gute Lösung. also besser die alten java-for-Schleifen
Was ist mit jool - Bibliothek ? cf-org.jooq.lambda.Deaktiviert-Paket
...und diese hier: stackoverflow.com/questions/31270759/...
github.com/TouK/ThrowingFunction
Die Lösung sieht wie einige, werfen Runtime-Ausnahmen, ich glaube es ist keine gute Lösung. also besser die alten java-for-Schleifen
Was ist mit jool - Bibliothek ? cf-org.jooq.lambda.Deaktiviert-Paket
InformationsquelleAutor Triton Man | 2013-08-12
Du musst angemeldet sein, um einen Kommentar abzugeben.
Müssen Sie eines der folgenden tun.
Wenn es dein code ist, dann definieren Sie Ihre eigene funktionale Schnittstelle, die erklärt, das überprüft, Ausnahme:
und Verwendung:
Ansonsten wrap
Integer myMethod(String s)
in eine Methode, die nicht erklären, eine geprüfte Ausnahme:dann:
oder:
Consumer
oderFunction
wenn Sie mit Standard-Methoden -- siehe meine Antwort unten.Ich denke, dass dies erreicht werden kann, als ein one-liner.
Kleine Optimierung: Statt
(String t) -> myWrappedMethod(t)
die Methode Referenzthis::myWrappedMethod
können auch verwendet werden.Vielleicht eine RuntimeException statt von UncheckedIOException wäre die bessere Wahl gewesen.
Eine noch allgemeinere Weise, es zu tun ist, um zu definieren, die überprüft, Funktion wie diese @FunctionalInterface public interface CheckedFunction<T, R, E extends Exception> { R apply(T t) throws E; } auf diese Weise können Sie auch definieren, die Ausnahme, die die Funktion werfen und wiederverwenden können die Schnittstelle für jeden code.
InformationsquelleAutor jason
Können Sie tatsächlich erweitern
Consumer
(undFunction
etc.) mit einer neuen Oberfläche, die Griffe Ausnahmen -, die mit Java 8 ist Standard-Methoden!Betrachten Sie dieses interface (extends
Consumer
):Dann zum Beispiel, wenn Sie eine Liste haben:
Wenn Sie wollen konsumieren (zB. mit
forEach
) mit einigen code, der exceptions wirft, Sie würden traditionell eingerichtet haben, einen try/catch-block:Aber mit dieser neuen Schnittstelle können Sie instanziieren es mit lambda-Ausdrücken und der compiler sich nicht beschweren:
Oder auch nur wirken, werden kurz und bündig!:
Update: Sieht aus wie es ein sehr schönes utility library Teil Durian genannt Fehler die verwendet werden können, um dieses problem zu lösen, mit viel mehr Flexibilität. Zum Beispiel, in meiner Implementierung oben habe ich ausdrücklich definiert die Fehlerbehandlung Politik (
System.out...
oderthrow RuntimeException
), in der Erwägung, dass Durian die Fehler ermöglichen das anwenden einer Richtlinie auf das Fliegen über eine große Sammlung von utility-Methoden. Vielen Dank für teilen Sie es, @NedTwigg!.Beispiel für die Nutzung:
einige Zeit später... entschied ich mich für ungeprüfte Ausnahmen und keine weitere funktionale Schnittstellen oder neue libraries -> der einfache Weg, weniger Tippen, schneller Lieferung, ist es nicht.
Hier ist eine verbesserte version mit sneaky werfen idiom. Kein Auspacken RuntimeException in CheckException.
InformationsquelleAutor jlb
Ich denke Durian ist
Fehler
Klasse kombiniert viele der Vorteile der verschiedenen Vorschläge oben.Gehören Durian in Ihrem Projekt, können Sie entweder:
com.diffplug.durian:durian:3.3.0
Throwing.java
undErrors.java
Bitte beachten Sie, dass Durian hat keine neuen Versionen seit Juni 2016. Nicht ein show-stopper, aber etwas im Auge zu behalten.
Durian-Betreuer hier. Was ist kaputt? Wenn ein Benutzer findet einen Fehler oder eine wichtige fehlende feature, würden wir release ein bugfix schnell. Die Bibliothek ist einfach, damit hatten wir noch keine bug-reports, damit haben wir nicht benötigt, um release keine bugfixes.
InformationsquelleAutor Ned Twigg
Dies ist nicht spezifisch für Java 8. Sie versuchen, zu kompilieren etwas vergleichbares:
InformationsquelleAutor assylias
Disclaimer: ich habe nicht verwendet, die Java 8 noch nicht, nur darüber gelesen.
Function<String, Integer>
nicht werfenIOException
, so können Sie nicht, stellen Sie keine codethrows IOException
. Wenn Sie eine Methode aufrufen, die erwartet, dass einFunction<String, Integer>
, dann die lambda, die Sie übergeben der Methode kann nicht werfenIOException
- Zeit. Sie können entweder schreiben Sie einen lambda-Ausdruck wie folgt aus (ich denke, das ist die lambda-syntax, nicht sicher):Oder, wenn die Methode, die Sie vorbei an den lambda-Ausdruck ist eine, die Sie selber geschrieben haben, legen Sie eine neue funktionale Schnittstelle und verwenden, die als parameter-Typ anstelle von
Function<String, Integer>
:die
@FunctionalInterface
annotation ist nicht erforderlich, für die es verwendbar für Lambda-Ausdrücke. Es wird empfohlen, für die überprüfung obwohl.InformationsquelleAutor Adam R. Nelson
Wenn Sie nichts dagegen haben, verwenden Sie ein 3rd-party-lib (Vavr) könnten Sie schreiben,
Es hat auch die so genannte Versuchen Monade, die mit Fehlern umgeht:
Bitte Lesen Sie mehr hier.
Disclaimer: ich bin der Schöpfer von Vavr.
InformationsquelleAutor Daniel Dietrich
Können Sie unthrow wrapper
oder
InformationsquelleAutor SeregaLBN
Könnte man doch erstellen Sie Ihre eigenen FunctionalInterface, wirft als unten..
dann setzen Sie es mit Lambdas oder Hinweise, wie unten gezeigt.
InformationsquelleAutor JohnnyO
Können Sie.
Ausweitung @marcg 's
UtilException
und das hinzufügen generischer<E extends Exception>
wo notwendig: auf diese Weise, den compiler zu zwingen, Sie wieder hinzuzufügen, werfen Klauseln und alles ist so, wie wenn Sie werfen könnte überprüft Ausnahmen nativ auf java-8-streams.InformationsquelleAutor PaoloC
Dieses problem wurde stört mich auch; das ist, warum ich erstellt habe dieses Projekt.
Mit ihm können Sie tun:
Gibt es totla 39 definierten Schnittstellen der JDK solchen
Throwing
entspricht; diese sind alle@FunctionalInterface
s verwendet in Bächen (die BasisStream
aber auchIntStream
,LongStream
undDoubleStream
).Und wie jeder von Ihnen verlängern Ihre nicht werfen-Pendant, können Sie direkt verwenden, um Sie in lambdas:
Ist das Standardverhalten, dass, wenn Ihr werfen lambda löst eine geprüfte Ausnahme, ein
ThrownByLambdaException
geworfen wird mit der checked-exception als Ursache. Deshalb können Sie erfassen und bekommen die Ursache.Andere Funktionen sind ebenfalls verfügbar.
@FunctionalInterface public interface SupplierWithCE<T, X extends Exception> { T get() throws X; }
- diese Weise wird der Benutzer nicht brauchen, umThrowable
, aber die spezifische überprüft Ausnahme statt.das wäre ein Schmerz zu erklären Ausnahme, jedes mal wenn; auch, Sie können immer nur verwenden, sagen, .Anwendung (die) statt .doApply() und catch
ThrownByLambdaException
haben, müssen Sie die ursprüngliche exception als Ursache (oder können Sierethrow(...).as(MyRuntimeException.class)
)Ich denke, es ist (Art von) ein Weg, um dieses.
Ich habe das Problem gelöst vor langer Zeit als " gut; ich kann jetzt mit
Throwing.runnable()
und andere, immer mit verketten-FunktionenDer chaining-Funktion ist sehr cool! Mein Kommentar war, ob ThrowingRunnable sollten, haben Sie die generische Ausnahme ist oder nicht. Zoltan gefragt, ob Ihre Bibliothek kann das argument als einen generischen parameter, und Sie sagte, dass wäre ein Schmerz zu verwenden. Mein link war um einige Zeilen code, die zeigen, einen Weg, um die Ausnahmen generisch sein, ohne dass es ein Schmerz. Es sei denn, ich habe falsch gelesen, die Ausnahmen in Ihrer Bibliothek sind nicht generisch (das ist eine vernünftige design-Wahl, weil Sie nicht bekommen, viel utility, indem Sie Ihnen Generika).
InformationsquelleAutor fge
Ich hatte dieses problem mit der Klasse.Vorname und Klasse.newInstance innerhalb eines lambda, so habe ich nur:
Innerhalb der lambda, statt der aufrufenden Klasse.forName("myClass").newInstance (), die ich gerade genannt uncheckedNewInstanceForName ("myClass")
InformationsquelleAutor Sergio
Gibt es eine Menge gute Antworten hier schon geschrieben. Gerade zu lösen versucht, das problem mit einer anderen Perspektive. Its just my 2 cents, bitte korrigiert mich wenn ich irgendwo falsch.
Throws-Klausel in FunctionalInterface ist nicht eine gute Idee
Ich denke, dies ist wahrscheinlich nicht eine gute Idee durchzusetzen, wirft IOException, weil der folgenden Gründe
Sieht für mich wie ein anti-pattern Stream/Lambda. Die ganze Idee ist, dass der Anrufer entscheiden, was code und den Umgang mit der Ausnahme. In vielen Szenarien, die IOException möglicherweise nicht anwendbar sein für den client. Zum Beispiel, wenn der client ist immer der Wert aus dem cache/Speicher anstelle der Durchführung der tatsächlichen I/O.
Auch, die Verarbeitung von Ausnahmen in streams wird wirklich hässlich. Zum Beispiel, hier ist mein code Aussehen, wenn ich Sie benutzen deine API -
Hässlich ist es nicht? Außerdem, wie ich bereits in meinem ersten Punkt, dass die doSomeOperation Methode sein kann oder nicht, werfen IOException (abhängig von der Implementierung der client - /Anrufer), sondern weil der throws-Klausel in der FunctionalInterface Methode, die ich immer schreiben Sie die try-catch.
Was mache ich, wenn ich wirklich wissen, diese API throws IOException
Dann wohl wir sind verwirrend FunctionalInterface mit typischen Schnittstellen. Wenn Sie wissen, diese API werfen eine IOException, dann die meisten wahrscheinlich wissen Sie auch ein paar Standard/abstrakte Verhalten als gut. Ich denke, Sie sollten definieren Sie eine Schnittstelle und stellen Sie die Bibliothek (mit Standard - /abstract-Implementierung) wie folgt
Aber die try-catch-problem noch besteht für die Kunden. Wenn ich die benutzen deine API-stream, den ich noch behandeln müssen, IOException in scheußlichen try-catch-block.
Bieten eine Standard-stream-freundliche API wie folgt
Die Standard-Methode der consumer-Objekt als argument, die dafür verantwortlich ist, dass die Ausnahme behandelt. Nun ist aus client-Sicht, wird der code wie folgt Aussehen
Schön, Recht? Natürlich, logger oder anderen handling-Logik verwendet werden könnte, statt von Exception::printStackTrace.
Können Sie auch setzen Sie eine Methode ähnlich https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html#exceptionally-java.util.function.Function- . Was bedeutet, dass Sie können setzen Sie eine andere Methode, mit der Ausnahme vom vorherigen Aufruf der Methode. Der Nachteil ist, dass Sie sind jetzt dabei, Ihre APIs "stateful", was bedeutet, dass Sie brauchen, um zu behandeln, thread-Sicherheit und wird schließlich zu einer performance-hit. Nur eine option zu erwägen, wenn.
Stream
hob eine Ausnahme. Also, ich mag die Idee, mit einem exception-handler und die Ergebnisse filtern, die nicht gültig sind. Beachten Sie, dass Ihre MyAmazingAPI ist effektiv einFunctionalInterface
(daher könnte man hinzufügen, die @FunctionalInterface annotation). Auch Sie können einen default Wert anstelle der VerwendungOptional.empty()
.InformationsquelleAutor TriCore
Sneaky werfen idiom ermöglicht, unter Umgehung
CheckedException
des Lambda-Ausdrucks. Die Verpackung einerCheckedException
imRuntimeException
ist nicht gut für die strikte Fehlerbehandlung.Kann verwendet werden, als eine
Verbraucher
- Funktion, eine Java-Sammlung.Hier ist eine einfache und verbesserte version des jib ' s Antwort.
Diese nur wrapps der lambda-Ausdruck in eine rethrow. Es macht
CheckedException
rethrow alleException
wurde geworfen in Ihren lambda.Finden Sie eine vollständige code-und unit-tests hier.
InformationsquelleAutor myui
Andere Lösung die Verwendung einer wrapper-Funktion wäre wieder entweder eine Instanz der wrapper das Ergebnis sagen Erfolg, wenn alles gut gegangen ist, entweder eine Instanz von, sagen wir Scheitern.
Etwas code zur Verdeutlichung :
Einen einfachen Anwendungsfall :
InformationsquelleAutor yohan
Können Sie ET. ET ist eine kleine Java-8-Bibliothek für Ausnahme-Konvertierung/übersetzung.
Mit der ET sieht es wie folgt aus:
ExceptionTranslator
Instanzen sind thread-sicher und kann gemeinsam von mehreren Komponenten. Sie können konfigurieren, mehr spezifische Ausnahme conversion-Regeln (z.B.FooCheckedException -> BarRuntimeException
), wenn Sie möchten.Wenn keine anderen Vorschriften vorhanden sind, geprüft, Ausnahmen werden automatisch umgewandelt
RuntimeException
.(Disclaimer: ich bin der Autor von ET)
Hi Tagir, danke für den Hinweis. Ich aktualisierte die Antwort.
InformationsquelleAutor micha
Was ich Tue, ist, um dem Benutzer zu ermöglichen, den Stellenwert geben den er eigentlich will, im Fall der Ausnahme .
Also ich habe etwas suchen, wie diese
Und diese kann dann rufen wie :
InformationsquelleAutor mmounirou
Erstellen Sie eine benutzerdefinierte return-Typ, der propagiert, die checked exception. Dies ist eine alternative zum erstellen einer neuen Schnittstelle, die Spiegel der vorhandenen funktionalen Schnittstelle mit der leichten Modifikation der "throws exception" auf die funktionale Schnittstelle einer Methode.
Definition
CheckedValueSupplier
CheckedValue
Nutzung
Was ist Los?
Hinzufügen "throws exception" zu jedem funktionalen Schnittstelle, die in der JDK würde gegen das DRY-Prinzip in den meisten abscheulichen Mode. Um dies zu vermeiden, wird eine einzelne funktionale Schnittstelle, löst eine geprüfte Ausnahme ist erstellt (
CheckedValueSupplier
). Dies wird die einzige funktionsfähige Schnittstelle, die es ermöglicht checked exceptions. Alle anderen funktionalen Schnittstellen nutzen, dieCheckedValueSupplier
wrap-code, löst eine geprüfte Ausnahme.Den
CheckedValue
Klasse halten wird das Ergebnis der Ausführung jeder Logik, dass löst eine geprüfte Ausnahme aus. Dies verhindert die Ausbreitung von eine geprüfte Ausnahme bis zu dem Punkt, an dem code versucht, auf den Wert, der eine Instanz vonCheckedValue
enthält.Die Probleme mit diesem Ansatz.
CheckedValue#get()
genannt wird.Verbraucher et al
Einige funktionale Schnittstellen (
Consumer
zum Beispiel), müssen behandelt werden, in einer anderen Weise, als Sie nicht liefern einen Wert zurück.Funktion statt der Verbraucher
Ein Ansatz, um eine Funktion zu verwenden, anstatt ein Verbraucher ist, gilt beim Umgang mit streams.
Eskalieren
Alternativ, Sie kann immer eskalieren, um eine
RuntimeException
. Gibt es andere Antworten, die Abdeckung Eskalation eine geprüfte Ausnahme aus in einemConsumer
.Nicht verbrauchen.
Nur vermeiden, funktionale Schnittstellen, die alle zusammen und verwenden Sie eine gute-ole-fashioned for-Schleife.
InformationsquelleAutor justin.hughey
Standardmäßig Java 8 Funktion es nicht erlaubt, Ausnahme auslösen und wie vorgeschlagen in mehrere Antworten gibt es viele Möglichkeiten, es zu erreichen, ist ein Weg:
Definieren als:
Und fügen Sie
throws
odertry/catch
die gleiche Ausnahme in der Aufrufer-Methode.InformationsquelleAutor Arpit
Wenn es Ihnen nichts ausmacht mit einer Drittanbieter-Bibliothek, mit cyclops-reagieren, eine Bibliothek, die ich zu tragen, können Sie die FluentFunctions - API zu schreiben
ofChecked dauert jOOλ CheckedFunction und gibt die Referenz erweicht zurück zu einem standard (nicht aktiviert) java JDK.util.Funktion.Funktion.
Alternativ können Sie halten die Arbeit mit den aufgezeichneten Funktion über die FluentFunctions api!
Beispielsweise für die Ausführung Ihrer Methode zu wiederholen, die es bis zu 5-mal und protokollieren Sie den status Sie können schreiben,
InformationsquelleAutor John McClean
Mehrere der angebotenen Lösungen verwenden ein generisches argument von-E zu übergeben, die den Typ der Ausnahme, die geworfen erhält.
Einen Schritt weiter, und anstatt der Typ der Ausnahme, pass in einen Verbraucher, der den Typ der Ausnahme, wie in...
Erstellen Sie mehrere wieder verwendbare Varianten von
Consumer<Exception>
dem gemeinsamen exception-handling-Anforderungen Ihrer Anwendung.InformationsquelleAutor Rodney P. Barbati
Werde ich etwas tun, generic:
Verwendung:
InformationsquelleAutor ahll
Verwenden
Jool Library
oder sagenjOOλ library
ausJOOQ
. Es bietet nicht nur eine unchecked exception behandelt, Schnittstellen, sondern bietet auch die Seq-Klasse mit vielen nützlichen Methoden.Beinhaltet auch Funktionale Schnittstellen mit bis zu 16 Parametern. Außerdem bietet es die Tuple-Klasse, die in verschiedenen Szenarien eingesetzt.
Jool Git Link
Speziell in der Bibliothek-Suche für
org.jooq.lambda.fi.util.function
Paket. Es enthält alle Schnittstellen aus Java-8 mit Überprüft vorangestellt. Siehe unten für Referenz:-InformationsquelleAutor Vinay Prajapati
Ich bin der Autor eine kleine lib mit einige generische magic zu werfen, der beliebige Java-Ausnahme überall ohne die Notwendigkeit von fangen Sie noch das einwickeln von Ihnen in
RuntimeException
.Verwendung:
unchecked(() -> methodThrowingCheckedException())
Quelle: https://github.com/qoomon/unchecked-exceptions-java
InformationsquelleAutor qoomon
Sie können fixieren Sie Ihre Präsentation durch den Einsatz von 4-Abstand, statt
<code>/<code>
🙂InformationsquelleAutor Franky Knuckels