如何在Java 8的Consumer中抛出异常

5
有没有办法在使用Java 8中的消费者时抛出异常?
例如:
    private void fooMethod(List<String> list) throws Exception {

    list.forEach(element->{
        if(element.equals("a")) {
            throw new Exception("error!");
        }
    });

}

这个报错提示: Unhandled exception type Exception

在这种情况下,正确的抛出异常方式是什么?


if(list.contains("a")) throw new Exception("error!"); - Holger
1
看起来好像几年前已经有人问过这个问题了。Java 8 Lambda function that throws exception?。在发布您的问题之前您没有谷歌搜索“java lambda throw exception”吗? 您是否阅读了期望 Stack Overflow 用户进行多少研究工作? - Abra
3个回答

5

由于Exception及其子类(除了RuntimeException)是已检查的异常,在lambda表达式中无法抛出已检查的异常。因此,您应该使用RuntimeException:

private void fooMethod(List<String> list) throws Exception {
    list.forEach(element->{
        if(element.equals("a")) {
            throw new RuntimException("error!");
        }
    });
}

4
你可以使用 Apache Commons Lang3 库完成它。

https://commons.apache.org/proper/commons-lang/javadocs/api-release/org/apache/commons/lang3/function/Failable.html

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

你可以写下以下内容:
import org.apache.commons.lang3.function.Failable;

private void fooMethod(List<String> list) throws Exception {
    list.forEach(Failable.asConsumer(element->{
        if(element.equals("a")) {
            throw new Exception("error!");
        }
    }));
}

3

流和相关类不设计使用受检查的异常。但是在代码的任何点都可以抛出RuntimeException,所以关键是抛出一个运行时异常,其原因(异常链接)是适当的受检查异常:

private void fooMethod(List<String> list) throws Exception {   
    list.forEach(element->{
        if(element.equals("a")) {
            throw new Runtime(new Exception("error!"));
        }
    });  
}

那么在捕获代码中,您只需要获取原始的检查异常封装:

try {
    fooMethod(someList);
} catch(Throwable e) {
    Exception ex = e.getCause();
}

谢谢你的回答,捕获Throwable不是一个坏习惯吗? - OEH
1
有些人会这么说,但在这种情况下它被用作“通用”的例子... 你必须解释并根据自己的需求进行调整。 - Jean-Baptiste Yunès

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接