从lambda抛出异常[重复]
Posted
技术标签:
【中文标题】从lambda抛出异常[重复]【英文标题】:Throwing exception from lambda [duplicate] 【发布时间】:2015-10-16 17:47:37 【问题描述】:鉴于此 java 8 代码
public Server send(String message)
sessions.parallelStream()
.map(Session::getBasicRemote)
.forEach(basic ->
try
basic.sendText(message);
catch (IOException e)
e.printStackTrace();
);
return this;
我们如何正确地将这个IOException
委派到方法调用的堆栈上? (简而言之如何让这个方法抛出这个IOException
?)
java 中的 Lambdas 看起来对错误处理不是很友好......
【问题讨论】:
【参考方案1】:我的方法是偷偷地从 lambda 中抛出它,但要注意让 send
方法在其 throws
子句中声明它。使用Exceptional
类I posted here:
public Server send(String message) throws IOException
sessions.parallelStream()
.map(Session::getBasicRemote)
.forEach(basic -> Exceptional.from(() -> basic.sendText(message)).get());
return this;
通过这种方式,您可以有效地让编译器稍微“移开视线”,在代码中的某个位置禁用其异常检查,但是通过在 send
方法上声明异常,您可以恢复正常行为它的所有调用者。
【讨论】:
哦,现在我喜欢这样。这确实是很偷偷摸摸的。【参考方案2】:我 wrote an extension 到 Stream API,它允许抛出检查的异常。
public Server send(String message) throws IOException
ThrowingStream.of(sessions, IOException.class)
.parallelStream()
.map(Session::getBasicRemote)
.forEach(basic -> basic.sendText(message));
return this;
【讨论】:
谢谢,现在这是一个非常好的界面 :) 一定会检查你的源代码【参考方案3】:问题确实是所有在 lambdas 中使用的@FunctionalInterface
s 都不允许抛出异常,除了未经检查的异常。
一种解决方案是使用a package of mine;有了它,您的代码可以读取:
sessions.parallelStream()
.map(Session::getBasicRemote)
.forEach(Throwing.consumer(basic -> basic.sendText(message)));
return this;
【讨论】:
那如何让send
抛出异常?
@MarkoTopolnik:我明白这一点。但是要让send
抛出IOException
,还需要很多 的工作。如果我没记错的话,你基本上必须抓住ThrownByLambdaException
,然后有一系列instanceof
来找出实际的异常是什么,这样你就可以重新抛出它。对于一两个例外情况可能还不错,但仍然非常冗长。
@T.J.Crowder 为了公平对待我们的同事 fge(正如你在我们的聊天中发现的那样),throwing-lambdas
确实支持偷偷摸摸的投掷成语。
@MarkoTopolnik:尽管据我所知,上面并没有真正使用它,也没有解释(例如,如果它确实使用了偷偷摸摸的投掷,throws
decl. on send
是必不可少的,编译器不会强迫你添加它)。以上是关于从lambda抛出异常[重复]的主要内容,如果未能解决你的问题,请参考以下文章