一个小故事(好吧,很多):我一直致力于创建采用java.util.function
类型的类,并使用try/catch
块来执行它们的执行从lambda语句中删除使用try/catch
的必要性。允许这个测试代码的东西:
list.forEach(ExceptionWrapper.wrapConsumer(s -> {throw new Exception(s);}));
这样做,我想出了这个。它确实 不 工作。
public class ExceptionWrapper {
public static <T> Consumer<T> wrapConsumer(Consumer<T> consumer){
return t -> {
try {
consumer.accept(t);
} catch (Exception e) {
throw new RuntimeException(e);
}
};
}
}
许多咒语总是导致
Error:(54, 61) java: unreported exception java.lang.Exception; must be caught or declared to be thrown
经过多次搜索,我发现了jOOλ代码。它看起来几乎相同,只是它们使用模仿包装类型的中间lambda构造,但声明抛出异常。我自己做了( 不 复制代码,只是概念)并且它的工作非常棒
public interface ConsumerWrapper<T>{
void accept(T t) throws Exception;
}
并在ExceptionWrapper
public static <T> Consumer<T> wrapConsumer(ConsumerWrapper<T> consumer){
... // ^ note change
}
允许编译和运行初始测试代码。
public static void main(String[] args) {
List<String> strings = Arrays.asList("1");
strings.forEach(System.out::println);
strings.forEach(ExceptionWrapper.wrapConsumer(s -> {throw new Exception(s);}));
}
Exception in thread "main" java.lang.RuntimeException: java.lang.Exception: 1 at crap.unk.ExceptionWrapper.lambda$wrapConsumer$2(ExceptionWrapper.java:39) at crap.unk.ExceptionWrapper$$Lambda$3/1401420256.accept(Unknown Source) ... Caused by: java.lang.Exception: 1 at crap.unk.ExceptionWrapper.lambda$main$3(ExceptionWrapper.java:54) at crap.unk.ExceptionWrapper$$Lambda$2/501263526.accept(Unknown Source)
throws
条款的差异引起的,但我不明白为什么。为什么它不同于将Object
关闭传递给方法并使用try/catch
来调用?
答案 0 :(得分:2)
您wrapConsumer
的初始尝试无效,因为它仍然需要Consumer
作为参数,而您尝试换行的lambda表达式仍会引发Exception
- - 检查异常。您的try
/ catch
离抛出的异常太远,因为在您创建lambda表达式时,您已在那里创建Consumer
,Consumer
's accept
method并未声明抛出任何已检查的异常。
接受ConsumerWrapper
的更改有效,因为该接口的方法声明允许它使用Exception
抛出throws Exception
。这允许您创建一个抛出已检查异常的lambda表达式。