处理 lambda 中的已检查异常 [重复]
Posted
技术标签:
【中文标题】处理 lambda 中的已检查异常 [重复]【英文标题】:Handle checked exception in lambda [duplicate] 【发布时间】:2020-05-20 09:08:26 【问题描述】:我有一些代码会引发检查异常。我想在 lambda 中调用该代码,以便从另一个地图创建地图:
Map<String, Coordinate> map = getMap();
Map<String, Integer> result = map.entrySet().stream().collect(
toMap(x -> x.getKey(), x -> doSomething(x.getValue)));
其中doSometing
是引发异常的代码:
int doSomething(Coordinate c) throws MyException ...
现在编译器肯定会抱怨没有处理异常。所以我用try-catch
包围它,看起来很丑:
Map<String, Integer> result = map.entrySet().stream().collect(
toMap(x -> x.getKey(), x ->
try
return doSomething(x.getValue());
catch (MyException e)
e.printStackTrace();
// return some error-code here???
));
这也不能编译,因为我们需要在catch
-case 中返回一些东西。然而,在这种特殊情况下,在这里返回任何东西没有多大意义,这就是为什么我实际上不想在那个级别处理异常。我不能只处理我的调用代码中的异常,我在哪里创建 lambda?所以说只是上一层?
try
Map<String, Integer> result = ...
catch (MyException e) ...
但这并不能编译,因为从 lambda 抛出的异常没有得到处理。
【问题讨论】:
这里的问题是,你为什么要使用检查异常。另外,我相信在 labdas 中处理已检查异常的标准方法(如果你不能让它运行时)是在 lamda 中捕获它并重新抛出一个未检查的异常 - 你可以使用已检查的异常作为原因。 @Worthless 不幸的是,doSomething
是一个 3rd-party-API,只是抛出。
那么是的,重新抛出可能是最简单的处理方法。
@Worthless 但是如何以一种好的方式做到这一点?难道就不能让异常在层层中冒泡,直到它最终被处理吗?
检查的异常在处理之前不能冒泡。每个中间方法都必须声明它。
【参考方案1】:
来自Baeldung's blog:你可以定义可以抛出Exception
的消费者:
@FunctionalInterface
public interface ThrowingConsumer<T, E extends Exception>
void accept(T t) throws E;
和一个静态包装器将检查的异常映射到RuntimeException
:
static <T> Consumer<T> throwingConsumerWrapper(
ThrowingConsumer<T, Exception> throwingConsumer)
return i ->
try
throwingConsumer.accept(i);
catch (Exception ex)
throw new RuntimeException(ex);
;
那么你就可以调用它了:
Map<String, Integer> result = map.entrySet().stream()
.collect(
throwingConsumerWrapper(toMap(x -> x.getKey(), x -> doSomething(x.getValue)))
);
【讨论】:
我已经找到了这个,但我无法让toMap
工作,因为我刚刚包装了 x -> doSomething
部分。谢谢你的回答。【参考方案2】:
过滤你的价值观是最值得的。如果您有可能引发异常的值。
然后您可以使用一种流行的包装器(即jooq.lambda)或编写自己的包装器
map.entrySet().stream()
.filter(x -> makeSureNoExtection(x))
.collect(toMap(x -> x.getKey(), unchecked(x -> doSomething(x.getValue))));
【讨论】:
以上是关于处理 lambda 中的已检查异常 [重复]的主要内容,如果未能解决你的问题,请参考以下文章