为什么使用
ifPresentOrElse
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 lambdas,所以我不知道这是否同样适用于java 9可选。
有什么想法吗?
您必须将投掷括在大括号内:
*() -> { throw new BookNotFoundException(); }*
当您想要指定两个非抛出操作时,方法
ifPresentOrElse
是一个有用的工具,以便在任何一种情况下都可以在方法调用后继续。但是当你想抛出缺少值的情况时,这是一个不必要的复杂化。只需使用
var book = dao.findBook(id).orElseThrow(BookNotFoundException::new);
printingService.print(book, printerName);
changeBookPrintDate(book.getId(), LocalDateTime.now());
由于此构造将抛出不存在的值,因此代码流将仅针对当前值继续。所以你可以在后续代码中像普通局部变量一样使用
book
,但保证它永远不会是null
。
orElseThrow
期望抛出异常的是 Supplier
,而不是抛出异常的函数。这样,供应商可以构造一个已检查的异常而不抛出它,并且 orElseThrow
的通用签名声明抛出供应商生成的任何类型。
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X