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

当使用Java可选的ifPresentOrElse方法时,无法引发“checked”异常

符正信
2023-03-14

为什么在使用java可选方法时,不能在orElse部分抛出选中的异常?

例如:

dao.findBook(id).ifPresentOrElse(book -> {
    printingService.print(book, printerName);
    changeBookPrintDate(book.getId(), LocalDateTime.now());
}, () -> new BookNotFoundException());

其中BookNotFoundException是扩展Exception类的自定义异常(检查异常)。

但是这段代码让编译器感到不安:

unreported exception com...exception.BookNotFoundException; must be caught or declared to be thrown

(知道它已经在方法声明中抛出,并且用try-catch包围这个块并不能解决编译问题)。

但是,如果我们使BookNotFoundException扩展RuntimeException(未选中),那么所有工作都完美。

有人知道为什么吗?

在这个java 9可选方法中阻止抛出此类异常的原因是什么?

为什么我要将我的异常设置为RuntimeException以使其工作,而它更应该被视为“自定义异常”而不是“运行时”?

这个问题解决的是同一个问题,但对于java 8 Lambda,所以我不知道这是否适用于java 9 Optionals。

其他研究只能证明这是不可能的。

任何想法?

共有2个答案

霍锦
2023-03-14

您必须添加带有方括号的投掷:

*() -> { throw new BookNotFoundException(); }*
程俊力
2023-03-14

当您想要指定两个非抛出动作时,方法ifPresentOrElse是一个有用的工具,这样您就可以在两种情况下的方法调用后继续。但是当你想在缺少值的情况下抛出时,这是一个不必要的复杂问题。只需使用

var book = dao.findBook(id).orElseThrow(BookNotFoundException::new);
printingService.print(book, printerName);
changeBookPrintDate(book.getId(), LocalDateTime.now());

由于此构造将抛出一个不存在的值,因此代码流将仅对现值继续。因此,您可以像普通局部变量一样在后续代码中使用book,但保证它永远不会是null

该方法要求抛出异常的供应商,而不是抛出的函数。这样,供应商就可以在不引发异常的情况下构造一个已检查异常,并且orElseThrow的泛型签名声明引发供应商生成的任何类型的异常。

<代码>公共

 类似资料:
  • 问题内容: 这是我的代码块。 这段代码无法编译,因为我在Line1中添加了“ throws”。 编译器抱怨重写的方法不能引发异常。 为什么这样 ?。 为什么覆盖的方法不能引发异常? 因为我可以通过在子类的实现中添加n行代码来覆盖基类中的方法。 这些添加的代码会引发异常,所以为什么我不能在重写的方法中使用“引发”? 问题答案: 重写的方法可以引发Exception,只要被重写的方法也抛出相同的Exc

  • 当方法运行时,我希望抛出一个异常(在测试时)。我能做的事情很少: 存根(mock.someMethod(“某些参数”)).ToThrow(new RuntimeException()); 当(mock.someMethod(“某些参数”)).thenThrow(new RuntimeException()) 放弃..... 通常我会创建一个spy对象来调用spied方法。使用stubbing我可以

  • 问题内容: 在Java线程中,“运行”方法不能引发“检查的异常”。我在Core Java(第1卷)书中遇到了这个问题。有人可以解释其背后的原因吗? 问题答案: 有人可以解释其背后的原因吗? 是的,因为您抛出的任何异常都会被JVM仔细忽略。因此,将其抛出可能是一个错误(除非您对该线程具有特定的异常处理程序,请参阅有关该文档的文档)。没有理由煽动潜在的错误行为。 或者举个例子。 编辑 为什么父线程不能

  • 我无法在Spring中捕获异步方法抛出的异常。我已经编写了一个未捕获的异常处理程序来捕获,但没有成功。该应用程序将启用启动任意数量的永远运行的异步作业。我认为我的异步方法需要返回Future,以便我可以将其存储在hashmap中并检查其状态或停止作业。我也可以通过存储它来获取所有正在运行的作业。我认为我不能使用get method of Future,因为如果输入正确,它会阻塞,我的作业将永远运行

  • 问题内容: 我正在审查为准备明天早上的期末考试而做的期中考试。我把这个问题弄错了,但是没有指出正确的答案,因此我忽略了询问教授。 考虑以下代码片段: 以下有关该代码的下列哪项正确? 主要方法旨在捕获和处理所有类型的异常。 主要方法是设计用来捕捉和处理鱼。 如果出现这种情况,则main方法应该简单地终止。 如果发生任何异常,main方法应该简单地终止。 我选择了第二个选项。 问题答案: 答案是数字4

  • 问题内容: 如何从Java 8流/ lambda中抛出CHECKED异常? 换句话说,我想使代码像这样编译: 由于上面的方法,因此该代码无法编译。 请注意,我不想将已检查的异常包装在运行时异常中,而是将已包装的未检查的异常抛出。我想抛出被检查的异常本身,而又不添加丑陋的流。 问题答案: 该帮助程序类使你可以在Java流中使用任何已检查的异常,如下所示: 注意抛出异常,已被选中。流本身也会抛出,而不