处理Java8流中的检查异常

时间:2018-09-17 11:40:32

标签: java

假设您有一个第三方库,该库公开了下一个界面。

interface Mapper {

    String doMap(String input) throws CheckedException;

}

class CheckedException extends Exception {

}

我知道检查异常通常在Java中是一种不好的做法,但是此代码来自第三方,我无法对其进行修改。

我想将Mapper接口的实现与Java8流API结合使用。请考虑下面的示例实现。

class MapperImpl implements Mapper {

    public String doMap(String input) throws CheckedException {
        return input;
    }

}

现在,例如,我想将映射器应用于字符串集合。

public static void main(String[] args) {
    List<String> strings = Arrays.asList("foo", "bar", "baz");
    Mapper mapper = new MapperImpl();

    List<String> mappedStrings = strings
            .stream()
            .map(mapper::doMap)
            .collect(Collectors.toList());
}

代码无法编译,因为Function不知道如何处理doMap声明的CheckedException。我想出了两种可能的解决方案。

解决方案#1-包装调用

.map(value -> {
                try {
                    return mapper.doMap(value);
                } catch (CheckedException e) {
                    throw new UncheckedException();
                }
            })

解决方案2-编写实用程序方法

public static final String uncheck (Mapper mapper, String input){
    try {
        return mapper.doMap(input);
    } catch (CheckedException e){
        throw new UncheckedException();
    }
}

然后我可以使用

.map(value -> Utils.uncheck(mapper, value))

您认为哪种方法是在Java8流(以及更广泛的lambda表达式)中处理检查异常的最佳方法?

谢谢!

2 个答案:

答案 0 :(得分:3)

您基本上列出了两个可行的选择。

另一种选择是将已检查的异常从流处理功能中抛出(“传播”或“隐瞒”已检查的异常)。通过捕获已检查的异常并将其重新抛出为RuntimeException(通过强制转换)来完成。看看this great answer了解详情。

已经开发了多个库来处理流API中的异常处理。 例如,您可以看一下NoException库:https://noexception.machinezoo.com/

它为您提供了一种方便的方法来包装/潜行/记录/忽略已检查或未检查的异常。

例如,在您的情况下为:

.map(value -> Exceptions.sneak().function(mapper::doMap))

.map(value -> Exceptions.wrap().function(mapper::doMap))

P.S .:我既不是该库的作者,也不是贡献者,但我已经在多个项目中使用了该库。

答案 1 :(得分:1)

您可以查看库faux-pas,该库简化了Java中的函数式编程的错误处理。我认为在流中管理检查异常很好。


P.S .:我既不是该库的作者,也不是贡献者,但是我已经在多个项目中使用了该库。

相关问题