当前位置: 首页 > 知识库问答 >
问题:

为什么我必须在提供lambda参数时捕获异常?

陆晓博
2023-03-14

考虑以下示例:

public class LambdaArgsTest {
    private static void display(Supplier<?> arg) {
        try {
            // this is the place where the Exception("wrong") might be thrown
            // and it is in fact handled
            System.out.println(arg.get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        display(() -> {
            if(/*some condition*/) {
                // this statement will be rejected due to unhandled exception
                throw new Exception("wrong");
            }
            return "abcde";
        });
    }
}

问题来了:上例中的lambda参数是稍后将在“display()”方法内执行的对象。将参数传递给“display()”时,它显然不会执行。

为什么它被编译器拒绝?我认为只有在实际调用lambda时,用try... catch来包围它是很合理的。

共有1个答案

徐隐水
2023-03-14

这是因为供应商功能界面的签名:

T get();

如您所见,方法get没有声明为抛出异常(也没有任何其他选中的异常)。

在Java中,有选中异常和未选中异常(未选中异常是从RuntimeException继承的异常)。必须处理选中的异常,要么在块中捕捉它们,要么声明方法抛出该异常。

如果供应商签字。get是:

T get() throws Exception:

代码可以很好地编译。

尝试抛出运行时异常(RuntimeException),而不是抛出异常(Exception),代码就会编译好。

编辑:根据Peter Lawrey在评论中的建议,如果确实需要从lambda表达式中抛出选中的异常,可以使用例如可调用的,其唯一一个方法的签名如下:

T call() throws Exception;

您只需要将一个可调用的方法传递给您的display方法,而不是供应商。

 类似资料:
  • 我必须用一些代码来回答这个问题: 假设我编写了以下方法规范: 您正在为一个将使用此方法的数据库程序编写代码,并且希望专门处理每个程序。try/catch子句应该是什么样的 您可以对catch子句内容使用no-ops——空块{}<我们只对这里语句的语法和结构感兴趣。 我回答说: 出于这个原因,他没有接受这个答案: “你的catch子句顺序不对。你能解释一下为什么顺序很重要吗?” 他的回答正确吗?

  • 问题内容: 如果我删除in : github.com/creating_web_app_go/main.go:8:不能在http.HandleFunc的参数中使用func文字(类型func(http.ResponseWriter,http.Request))作为func(http.ResponseWriter,* http.Request)类型。 我对Go和指针都很陌生。 所以问题是,为什么必须是

  • 问题内容: 有时,当我重写方法时,在第一次调用时会出现异常,如下所示: 为什么我们被迫打电话?父类有义务是有意义的,但是更重要的是,我们如何知道需要调用一个方法,而不是等待它崩溃? 问题答案: 为什么我们被迫调用super.method()? 组成Android SDK的类非常复杂。例如,活动和片段都必须执行许多操作才能正常运行(即管理生命周期,优化内存使用,在屏幕上绘制布局等)。要求客户端调用基

  • 我试图在JUnit 5中开发一个参数化测试,如下例所示。 尝试运行测试导致异常: 您必须为此@ParameterizedTest提供至少一个参数 这个信息让我觉得,我做错了什么,不是吗? p、 我有一个假设,只有原语类型的参数可用。

  • 问题内容: 我创建了一个用于显示工具提示的指令: 对应功能: 应用于此: 这是我观点的一部分,由拥有者的控制器处理 为什么必须调用才能将更改应用到,该更改是早先声明和初始化的? 问题答案: 因为附加到事件的回调超出了angular的范围;angular不知道该函数何时运行/结束,因此摘要循环永远不会运行。 调用或告诉angular更新绑定并触发任何手表。

  • 问题内容: 每个人都告诉我“使用super.viewDidLoad()因为它就是这样”或“我一直那样做,所以要保留它”,“如果不叫super就是错误的”等。 我只发现了一些有关Objective-C用例的主题,这些主题并没有那么启发性,但是我正在Swift 3中进行开发,所以有什么专家可以给我一个很好的详细解释吗? 这是一种良好实践的案例还是有任何隐藏的影响? 问题答案: 通常,最好为您覆盖的所有