为了账号安全,请及时绑定邮箱和手机立即绑定

Java lambda 不适用于完整定义

Java lambda 不适用于完整定义

繁星淼淼 2022-11-30 13:26:50
我正在尝试包装抛出已检查异常的方法。我正在按照此网址中的步骤操作:https ://www.rainerhahnekamp.com/en/ignoring-exceptions-in-java/有趣的是,当我这样写代码时:IntStream.range(1, locales.length)            .mapToObj(i -> locales[i].toString())            .forEach(wrap(this::testLocale));它工作正常但是当我这样写时:IntStream.range(1, locales.length)            .mapToObj(i -> locales[i].toString())            .forEach(s -> wrap(testLocale(s)));Intellij 抱怨“未处理的异常:java.lang.Exception”这里 testLocale 看起来像这样:void testLocale(String s) throws Exception包装函数如下所示:public static <T> Consumer<T> wrap(WrapConsumer<T> wrapper) {    return t -> {        try {            wrapper.accept(t);        } catch(Exception exception) {            throw new RuntimeException(exception);        }    };}而 WrapConsumer 是带有 Consumer 签名的函数接口:@FunctionalInterfacepublic interface WrapConsumer<T> {   void accept(T t) throws Exception;}我正在努力理解为什么 Intellij 根据我编写 lambda 的方式抱怨
查看完整描述

3 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

您应该通过以下方式提供包装好的消费者forEach

.forEach(wrap(this::testLocale));

您正在做s -> wrap(testLocale(s))的是提供一个仍然无法处理已检查异常的新消费者。

可能更容易理解的是forEach接受Consumer具有以下方法定义的 a:

void accept(T t); // does not define to throw the checked Exception

当你这样做的时候,你正在使用forEach(s -> ...)的就是这个。Consumer::accept

另一方面,forEach(wrap(this::testLocale));它将返回一个Consumer静止图像,但是通过接受一个WrapConsumer<T> wrapper确实声明通过以下方式抛出Exception输入作为输入:

void accept(T t) throws Exception;


查看完整回答
反对 回复 2022-11-30
?
慕勒3428872

TA贡献1848条经验 获得超6个赞

只是补充 Eugene 的回答,您期望方法 wrap() 将消费者作为参数,而不是返回 void 的调用方法。

您可以通过从 testLocale 方法中删除 throws Exception 来证明这一点。

IDE 会给你错误:

"reason: no instance(s) of type variable(s) T exist so that void conforms to WrapConsumer<T>"

您编写的代码(正确的消费者)的类似代码:

IntStream.range(1, locales.length)
        .mapToObj(i -> locales[i].toString())
        .forEach(wrap(this::testLocale));

将会:

IntStream.range(1, locales.length)
        .mapToObj(i -> locales[i].toString())
        .forEach(wrap(l-> testLocale(l)));


查看完整回答
反对 回复 2022-11-30
?
四季花海

TA贡献1811条经验 获得超5个赞

您只是缺少正确的 lambda 语法。您当前的代码正在调用 wrap一个void参数:-(wrap(testLocale(s))具有testLocale(s)void 返回类型)

您需要的正确 lambda 表达式是:

.forEach(wrap(s -> testLocale(s)));

wrap返回一个函数,因此您不需要延迟执行它(即,不需要调用 的函数wrap)。


查看完整回答
反对 回复 2022-11-30
  • 3 回答
  • 0 关注
  • 147 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号