假设您有一个第三方库,该库公开了下一个界面。
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表达式)中处理检查异常的最佳方法?
谢谢!
答案 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)