如何从 Java 8 流/lambda 中抛出 CHECKED 异常?
换句话说,我想编译这样的代码:
public List<Class> getClasses() throws ClassNotFoundException {
List<Class> classes =
Stream.of("java.lang.Object", "java.lang.Integer", "java.lang.String")
.map(className -> Class.forName(className))
.collect(Collectors.toList());
return classes;
}
此代码无法编译,因为上面的 Class.forName()
方法抛出 ClassNotFoundException
,它已被检查。
请注意,我不想将已检查的异常包装在运行时异常中,而是抛出包装的未检查异常。 我想自己抛出已检查的异常,并且不向流中添加丑陋的 try
/ catches
。
原文由 MarcG 发布,翻译遵循 CC BY-SA 4.0 许可协议
这个
LambdaExceptionUtil
帮助程序类允许您在 Java 流中使用任何已检查的异常,如下所示:注意
Class::forName
抛出ClassNotFoundException
,已 检查。流本身也会抛出ClassNotFoundException
,而不是一些包装未经检查的异常。关于如何使用它的许多其他示例(静态导入后
LambdaExceptionUtil
):截至 2015 年 11 月的更新 代码在@PaoloC 的帮助下得到了改进, 请在下面查看他的回答并对其 进行投票。他帮助解决了最后一个问题:现在编译器会要求您添加 throw 子句,一切就好像您可以在 Java 8 流上本地抛出已检查的异常一样。
注 1 上面的
LambdaExceptionUtil
类的rethrow
方法可以放心使用,并且 可以在任何情况下使用。注 2: 上面的
LambdaExceptionUtil
类的uncheck
方法是奖励方法,如果您不想使用它们,可以安全地将它们从类中删除。如果您确实使用了它们,请小心使用,并且在了解以下用例、优点/缺点和限制之前不要这样做:• 如果调用的方法实际上永远不会抛出它声明的异常,则可以使用
uncheck
方法。例如:new String(byteArr, “UTF-8”) 抛出 UnsupportedEncodingException,但 Java 规范保证 UTF-8 始终存在。在这里,throws 声明是一件令人讨厌的事情,欢迎使用最小样板文件使其静音的任何解决方案:String text = uncheck(() -> new String(byteArr, "UTF-8"));
• 如果您正在实现一个严格的接口,在该接口中您没有添加抛出声明的选项,但抛出异常是完全合适的,那么您可以使用
uncheck
方法。包装异常只是为了获得抛出它的特权,这会导致堆栈跟踪中出现虚假异常,这些异常不会提供有关实际出错的信息。一个很好的例子是 Runnable.run(),它不会抛出任何已检查的异常。• 在任何情况下,如果您决定使用
uncheck
方法,请注意在没有 throws 子句的情况下抛出 CHECKED 异常的这两个后果:1) 调用代码将无法通过以下方式捕获它name(如果你尝试,编译器会说:Exception is never throw in the body of corresponding try statement)。它会冒泡并且可能被一些“catch Exception”或“catch Throwable”捕获在主程序循环中,这可能是你想要的。 2) 它违反了最小意外原则:不再足以捕获RuntimeException
以保证捕获所有可能的异常。出于这个原因,我认为这不应该在框架代码中完成,而只能在您完全控制的业务代码中完成。参考:
http://www.philandstuff.com/2012/04/28/sneakily-throwing-checked-exceptions.html
http://www.mail-archive.com/javaposse@googlegroups.com/msg05984.html
龙目岛项目注解:@SneakyThrows
Brian Goetz 的意见(反对)在这里: How can I throw CHECKED exceptions from inside Java 8 streams?
https://softwareengineering.stackexchange.com/questions/225931/workaround-for-java-checked-exceptions?newreg=ddf0dd15e8174af8ba52e091cf85688e *