从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 中使用的@FunctionalInterfaces 都不允许抛出异常,除了未经检查的异常。

一种解决方案是使用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抛出异常[重复]的主要内容,如果未能解决你的问题,请参考以下文章

从 lambda 表达式中抛出的已检查异常

在 Lambda 表达式中从 main() 抛出 IOException [重复]

如何在 lambda 表达式中重新抛出异常? [复制]

lambda表达式内出现异常无法throw抛出

为啥我看不到从 java 守护线程抛出的异常 [重复]

Django-cms Placeholderfield 不工作,抛出 lambda 异常