有些人试图说服您必须遵守规则。听,但是无论您是否服从,都应根据自己的情况决定自己。现实是“您应该遵守规则”(而不是“您必须遵守规则”)。请注意,如果您不遵守规则,可能会造成后果。
这种情况不仅适用于的情况Runnable
,而且在Java 8中也经常在Streams和其他引入了功能接口而无法处理受检查的异常的地方使用。例如Consumer
,Supplier
,Function
,BiFunction
等等都没有设施,以应付检查的异常被宣布。
那么情况和选择是什么?在下面的文字中,Runnable
表示没有声明异常或声明异常对手边用例而言有限的任何功能接口。
- 您已经声明了
Runnable
自己的位置,并且可以Runnable
用其他内容代替。
- 考虑更换
Runnable
带Callable<Void>
。基本上是一样的,但是允许抛出异常;并且必须return null
最后,这是一个轻微的烦恼。
- 考虑用
Runnable
您自己的自定义替换,@FunctionalInterface
该自定义可以完全抛出所需的异常。
- 您已经使用了API,并且可以使用其他替代方法。例如,某些Java API重载,因此您可以使用
Callable<Void>
代替Runnable
。
- 您已经使用了API,没有其他选择。在那种情况下,您仍然没有选择余地。
- 您可以在中包装例外
RuntimeException
。
- 您可以通过使用未经检查的强制转换将异常引入RuntimeException中。
您可以尝试以下方法。这有点hack,但是有时候我们需要hack。因为,是否应该检查异常是由其类型定义的,但实际上实际上应该由情况来定义。
@FunctionalInterface
public interface ThrowingRunnable extends Runnable {
@Override
default void run() {
try {
tryRun();
} catch (final Throwable t) {
throwUnchecked(t);
}
}
private static <E extends RuntimeException> void throwUnchecked(Throwable t) {
throw (E) t;
}
void tryRun() throws Throwable;
}
我更喜欢此方法,new RuntimeException(t)
因为它具有较短的堆栈跟踪。
您现在可以执行以下操作:
executorService.submit((ThrowingRunnable) () -> {throw new Exception()});
免责声明:当泛型类型信息不仅在编译时而且在运行时都处理时,在Java的将来版本中实际上可能会取消以这种方式执行未经检查的强制转换的功能。