java - 有什么方法可以在 block 之外从 foreach 的使用者捕获 RuntimeException 吗?

标签 java exception foreach stream runtimeexception

我有一些代码(还有一些嵌套的 forEach'sstreams):

void process() throws RuntimeException
{
    try {

        ArrayList<Integer> ints = new ArrayList<>();
        ints.add(1);
        ints.add(2);
        ints.add(3);

        ints.forEach(e -> {

            System.out.println(e);
            throw new RuntimeException("RuntimeException");

        });
    }
    catch (RuntimeException rex)
    {
        rex.printStackTrace();
        throw rex; // throw it up, and up, and up...
    }
}

它不起作用,因为foreach的 Consumer的 accept()默认情况下不会抛出异常。即使它有一个 throws 签名 - 我无法在 block 之外捕获它。

我需要做的是捕获 foreach() 方法本身的异常。

有什么方法可以在没有像这样的外部方法的情况下实现这一点

void handleException(RuntimeException ex){ ... }

并在每个 forEach()'s try/catch 中调用它?

最佳答案

我发现这个问题是错误的 - 它实际上确实适用于 RuntimeException

对于已检查的异常,有一个工作代码:

package Exporter;

import java.util.function.Consumer;
import java.util.function.Function;

public final class LambdaExceptions {

    @FunctionalInterface
    public interface Consumer_WithExceptions<T, E extends Exception> {
        void accept(T t) throws E;
    }

    @FunctionalInterface
    public interface Function_WithExceptions<T, R, E extends Exception> {
        R apply(T t) throws E;
    }

    /**
     * .forEach(rethrowConsumer(name -> System.out.println(Class.forName(name))));
     */
    public static <T, E extends Exception> Consumer<T> rethrowConsumer(Consumer_WithExceptions<T, E> consumer) throws E {
        return t -> {
            try {
                consumer.accept(t);
            } catch (Exception exception) {
                throwActualException(exception);
            }
        };
    }

    /**
     * .map(rethrowFunction(name -> Class.forName(name))) or .map(rethrowFunction(Class::forName))
     */
    public static <T, R, E extends Exception> Function<T, R> rethrowFunction(Function_WithExceptions<T, R, E> function) throws E  {
        return t -> {
            try {
                return function.apply(t);
            } catch (Exception exception) {
                throwActualException(exception);
                return null;
            }
        };
    }

    @SuppressWarnings("unchecked")
    private static <E extends Exception> void throwActualException(Exception exception) throws E {
        throw (E) exception;
    }

}

它就像一个魅力:

void process() throws RuntimeException
{
    try {
        ArrayList<Integer> ints = new ArrayList<>();
        ints.add(1);
        ints.add(2);
        ints.add(3);

        ints.forEach(LambdaExceptions.rethrowConsumer(e -> {
            System.out.println(e);
            throw new RuntimeException("RuntimeException");
        }));

    }
    catch (RuntimeException rex)
    {
        System.out.println("Got first exception");
        rex.printStackTrace();
        throw rex;
    }
}

关于java - 有什么方法可以在 block 之外从 foreach 的使用者捕获 RuntimeException 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46806417/

相关文章:

.net - 我们真的需要捕获 P/Invoke 方法的异常吗?

java - 抛出异常是否是处理 Java 反射 API 中抛出的所有异常的好方法?

php foreach循环来自2个表的mysql数据?

php - 使用 foreach 循环插入多个字段

PHP 数组对象/数组迭代器 : concept with example

java - 将 YV12 转换为 NV21 (YUV YCrCb 4 :2:0)

java - 如何设置 Set<String> 不区分大小写

java - 如何处理 Netty 中缓慢的读取器?

java - GUI应用程序中MVC模型之间的交互

java - "Can' t 覆盖原因”当使用空原因设置异常原因时