In der Java 8 Collection- und Stream-API ist Iteratable und in der for-Anweisung implementiert Sie können jetzt die Lambda-Formel für den Teil verwenden, den Sie berechnet haben.
Funktionale Schnittstellen wie Consumer sind jedoch nicht zum Auslösen von Ausnahmen definiert. Die Unfähigkeit, eine CheckedException (https://qiita.com/shunsuke227ono/items/142703c0b046f522f8bd) auszulösen, ist daher ein Nachteil des Lambda-Ausdrucks (https://teratail.com/questions/). 8461). Das Umschließen oder Zusammendrücken geprüfter Ausnahmen in Laufzeitausnahmen, die zur Kompilierungszeit nicht überprüft werden, ist aus Sicht der Ausnahmebehandlung nicht gut. ..
Qiita und Stackoverflow Auch i ku tsu / yoshi389111 / items / c6b7d373a00f8fd3d5f3) oder Eine Lösung wird angezeigt, aber [s: // //github.com/SeregaLBN/StreamUnthrower), das Lambda ist ein schlecht sichtbarer Code, [Schwere Implementierung für jede Funktionsschnittstelle](https://github.com/fge/throwing- lambdas / tree / master / src / main / java / com / github / fge / lambdas / konsumenten) oder nicht. Von Google Lehrer und alle sind besorgt / (´ω `;) \
Entpacken Sie die Laufzeit in CheckException. Ich möchte das nicht tun, weil der Code nicht sichtbar ist ...
try {
Arrays.asList(1, 2, 3).forEach(e -> {
try {
//Eine Geschäftslogik, die eine aktivierte Ausnahme auslöst
methodTrowingIOException(e.intValue());
} catch(IOException ex) {
// throw new UncheckedIOException(ex);
throw new RuntimeException(ex);
}
}));
} catch (RuntimeException re) {
Throwable e = re.getCause();//Check-Ausnahme auslösen
throw e;
}
Sie können [UncheckedIOException] verwenden (https://docs.oracle.com/javase/jp/8/docs/api/java/io/UncheckedIOException.html), aber das Auspacken ist problematisch und RuntimeException wird verwendet. Es ist nicht viel anders als.
@FunctionalInterface
public interface CheckedFunction<T, R> {
R apply(T t) throws Exception;
}
void foo (CheckedFunction f) { ... }
Dies ist jedoch ein [für jeden](https: /), der [Verbraucher] voraussetzt (https://docs.oracle.com/javase/jp/8/docs/api/java/util/function/Consumer.html). /docs.oracle.com/javase/jp/8/docs/api/java/lang/Iterable.html#forEach-java.util.function.Consumer-) usw., also abgelehnt.
Sneaky throw ist ein Java-Compiler-Typprüfungsgeheimnis, das eine überprüfte Ausnahme zur Kompilierungszeit in eine RuntimeException überführt [Lombok]( Dies ist die unter https://qiita.com/opengl-8080/items/671ffd4bf84fe5e32557) verwendete Technik. Dieser Artikel ist detailliert.
@SuppressWarnings("unchecked")
@Nonnull
public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
throw (E) ex;
}
//Ich löse eine IOException, aber ich brauche keine Throws oder Catch, weil der Compiler mich zu einer RuntimeException verleitet, aber tatsächlich eine IOException auslöst
@Test(expected = IOException.class)
public void testSneakyThrow() {
Throwing.sneakyThrow(new IOException());
}
Unter Anwendung dieser Redewendung definieren wir den folgenden Verbraucher.
import java.util.function.Consumer;
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
@Override
default void accept(final T e) {
try {
accept0(e);
} catch (Throwable ex) {
Throwing.sneakyThrow(ex);
}
}
void accept0(T e) throws Throwable;
}
Gehen Sie bei der Verwendung wie folgt vor. Der obige Throwing Consumer, der die Consumer-Schnittstelle erbt, wird zum Empfangen des Lambda verwendet. Dies ist eine erweiterte Version von StackOverflow Answer.
@Test
public void testThrowingConsumer() throws IOException {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach((ThrowingConsumer<Integer>) e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
});
}
Bei Throwing Consumer war der Teil, der den Lambda-Ausdruck für Each with Throwing Consumer erhält, etwas kompliziert auszudrücken. Ich möchte dies prägnanter gestalten.
public final class Throwing {
private Throwing() {}
@Nonnull
public static <T> Consumer<T> rethrow(@Nonnull final ThrowingConsumer<T> consumer) {
return consumer;
}
@SuppressWarnings("unchecked")
@Nonnull
public static <E extends Throwable> void sneakyThrow(@Nonnull Throwable ex) throws E {
throw (E) ex;
}
}
Wickeln Sie einfach den Lambda-Ausdruck mit der Rethrow-Methode ein. Dies ist meine bisherige endgültige Antwort.
Der Compiler geht davon aus, dass forEach nur eine Laufzeitausnahme ausgibt. Daher wird entweder IOException beim Aufrufer ausgelöst oder try / catch zum richtigen Zeitpunkt.
import static hivemall.utils.lambda.Throwing.rethrow;
@Test
public void testRethrow() throws IOException {
thrown.expect(IOException.class);
thrown.expectMessage("i=3");
Arrays.asList(1, 2, 3).forEach(rethrow(e -> {
int i = e.intValue();
if (i == 3) {
throw new IOException("i=" + i);
}
}));
}
Bitte lassen Sie mich wissen, ob es einen besseren Weg gibt.
Recommended Posts