Java 有没有办法从foreach';消费者,在街区外?

Java 有没有办法从foreach';消费者,在街区外?,java,exception,foreach,stream,runtimeexception,Java,Exception,Foreach,Stream,Runtimeexception,我有一些代码(还有一些嵌套的forEach的和流): void process()引发RuntimeException { 试一试{ ArrayList ints=新的ArrayList(); 加入(1); 内加(2); 加入(3); 国际航空公司(e->{ 系统输出打印ln(e); 抛出新的RuntimeException(“RuntimeException”); }); } 捕获(运行时异常rex) { printStackTrace(); 扔雷克斯;//扔上去,再上去,再上去。。。 } }

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

void process()引发RuntimeException
{
试一试{
ArrayList ints=新的ArrayList();
加入(1);
内加(2);
加入(3);
国际航空公司(e->{
系统输出打印ln(e);
抛出新的RuntimeException(“RuntimeException”);
});
}
捕获(运行时异常rex)
{
printStackTrace();
扔雷克斯;//扔上去,再上去,再上去。。。
}
}
它不起作用,因为默认情况下,
foreach的
消费者的
accept()
不会引发异常。即使它有一个
抛出的
签名,我也无法在块外捕捉到它

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

如果没有一些外部方法,比如

void handleException(RuntimeException ex){…}


在每个
forEach()的
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;
    }

}
包装出口商;
导入java.util.function.Consumer;
导入java.util.function.function;
公共最终类LambdaExceptions{
@功能接口
公共接口使用者(例外情况除外){
无效接受(T)抛出E;
}
@功能接口
公共接口功能(无例外){
R应用(T)抛出E;
}
/**
*.forEach(rethrowConsumer(name->System.out.println(Class.forName(name)));
*/
公共静态消费者rethrowConsumer(消费者\例外消费者)抛出E{
返回t->{
试一试{
消费者接受(t);
}捕获(异常){
一次性使用(例外);
}
};
}
/**
*.map(rethrowFunction(name->Class.forName(name)))或.map(rethrowFunction(Class::forName))
*/
公共静态函数rethrowFunction(函数_with exceptions函数)抛出E{
返回t->{
试一试{
返回函数。应用(t);
}捕获(异常){
一次性使用(例外);
返回null;
}
};
}
@抑制警告(“未选中”)
私有静态void throwActualException(异常异常)抛出{
抛出(E)异常;
}
}
它就像一个符咒:

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;
    }
}
void process()引发RuntimeException
{
试一试{
ArrayList ints=新的ArrayList();
加入(1);
内加(2);
加入(3);
ints.forEach(LambdaExceptions.rethrowConsumer(e->{
系统输出打印ln(e);
抛出新的RuntimeException(“RuntimeException”);
}));
}
捕获(运行时异常rex)
{
System.out.println(“获得第一个异常”);
printStackTrace();
扔雷克斯;
}
}

您应该显示您的实际代码,这听起来像是设计问题。此代码的可能副本正在使用
RuntimeException
它可以工作,但它是否掩盖了程序中可怕的设计缺陷?是否标记了我使用的API的可怕设计。为了回答您在主要帖子上的评论,我之所以需要这样做,是因为外部公司提供的API会在每个数据获取请求上抛出RuntimeEx。如果我有嵌套调用,例如获取文件夹、其子文件夹等的方法,并且该方法内部出现问题,我需要回滚整个任务。我可以将每个
foreach()
替换为一个简单的
for
,但它看起来真的不可读。如果你说用
for
替换它比创建包装更难看,我相信你的话。只要记住,情人眼里出西施。
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;
    }
}