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

为什么Lambda不理解抛出的方法签名?[副本]

吕德惠
2023-03-14

在下面的代码中,我在方法签名中编写了throws,但在Lambda for write中,编译器给出了一个错误。为什么?

编译器错误:未处理的异常:java.io.IOException

 public void saveTodoItems() throws IOException {

    try (BufferedWriter outputStream = new BufferedWriter(new OutputStreamWriter(
            new FileOutputStream("TodoItems.txt"), StandardCharsets.UTF_8))) {

        todoItems.forEach(todoItem -> {
                outputStream.write(todoItem.getShortDescription() + "\t" //compile error on write
                        + todoItem.getDetail() + "\t"
                        + todoItem.getDeadLine()+"\n");

        });
    }
}

共有1个答案

乜烨霖
2023-03-14

请记住,lambda应该是功能接口的实现。在这种情况下,forEach采用功能接口消费者

void forEach(Consumer<? super T> action)

因此,您的lambda实际上是在消费者接口-接受中实现单个抽象方法。此方法未声明为抛出任何异常:

void accept(T t); // no throws clause here at all!

因此,写入调用可能抛出的IOException被认为是未处理的。事实上,您已经在您的saveTodoItems方法中添加了一个throws子句,这与此无关。

另一方面,如果您声明了自己的函数接口,该接口在其单个抽象方法中确实有一个抛出子句:

interface IOConsumer<T> {
    void accept(T t) throws IOException;
}

可以写:

IOConsumer<TodoItem> consumer = todoItem -> {
    outputStream.write(todoItem.getShortDescription() + "\t"
                    + todoItem.getDetail() + "\t"
                    + todoItem.getDeadLine()+"\n");
};

当然,您不能在forEach中使用它,因为它只接受消费者,而不是IOConsumer。您应该用try…catch包围write,或者查看此处以获取更多替代方案。

 类似资料:
  • NodeJS版本8.11-警告是“此错误源于在没有catch块的情况下抛出异步函数,或者拒绝未用.catch()处理的promise。” 这两个都不是真的,您可以通过检查我的测试用例看出这一点: 翻转标志,查看相同的代码运行时是否有错误。

  • null 为简洁起见,排除了getter和setter(用于所有字段)以及toString()。 我尽了最大的努力按照指导原则格式化代码,但它没有发生,请耐心等待。 @Entity@Table(name=“Products”)@XmlRootElement@NamedQueries({@NamedQuery(name=“Product.FindAll”,query=“从产品p中选择p”),@nam

  • 问题内容: 阅读的JavaDoc ,我碰到了一个奇怪的方法签名;我一生中从未见过: 乍一看,我想知道通用异常怎么可能发生,因为您不能这样做(here和here)。再三考虑,这开始变得有意义,因为这里只是绑定…,但是供应商本身确切知道泛型之前应该是什么类型。 但是第二行打给我: 是完整的通用异常类型。 然后: 什么世界呢 这 是什么意思? 已绑定在方法签名中。 这将以任何方式解决通用异常限制吗? 为

  • 下面是我的代码。当我运行它时,我在线程“main”java.lang.IndexOutOfBoundsException:Index:3、Size:2中得到异常,而不是我的异常消息。谁能解释一下我做错了什么,为什么会这样?谢谢!

  • 我正在生成一个带有签名的PDF文档,我希望它启用LTV。为此,我在创建PDF时对其进行签名,然后添加包含DSS的第二个版本,其中包含与验证相关的信息(VRI)。正如我在一些文章中发现的,我需要添加证书链(没有根证书颁发机构)和证书吊销列表(CRL)。在我的例子中,两者都有两个元素。之后,我添加了VRI条目,它是签名内容(在/Contents中的第一个PDF版本中找到)的SHA-1散列,其值引用上述

  • 问题内容: 我第一次在方法签名中看到它。 我试图访问一个.class文件。它具有如下定义的方法 那个GraphData就是带有getter和setter的POJO。为什么显示.class文件而不是显示? 问题答案: 它是 varargs ,只能在参数列表中最后使用。最后一个参数可以容纳多个对象。 查看“ a”和“ b”如何转换为数组。