这些结构之间的区别是什么,一个不会编译? [英] What is the difference between these constructs such that one won't compile?
问题描述
有点背景故事(确定,很多):我一直在努力创建类 java.util.function
类型,用 try / catch
块包装它们的执行,以消除在lambda语句中使用 try / catch
的需要。允许此测试代码的任何东西:
A little backstory (ok, a lot): I've been working on creating classes that take java.util.function
types and wrap their execution with try/catch
blocks to remove the need for using try/catch
from within lambda statements. Something that would allow this test code:
list.forEach(ExceptionWrapper.wrapConsumer(s -> {throw new Exception(s);}));
在这样做的时候,我想出了这个。 不起作用。
In doing so, I came up with this. It did not work.
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λ code。它看起来几乎相同,除了他们使用一个中间lambda构造,模仿包装类型,但声明抛出异常。我做了我自己的( 不 复制代码,只是概念),它工作非常真棒
After much searching, I came across the jOOλ code. It looked nearly the same except they use an intermediary lambda construct that mimics the wrapped types but declares to throw an exception. I made my own (did NOT copy the code, just the concept) and it works pretty awesome
public interface ConsumerWrapper<T>{
void accept(T t) throws Exception;
}
并将更改 ExceptionWrapper
public static <T> Consumer<T> wrapConsumer(ConsumerWrapper<T> consumer){
... // ^ note change
}
允许初始测试代码编译和运行。
allows the initial test code to compile and run.
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
p> THE QUESTION
Why wouldn't my original attempt work? Why does the use of the intermediary, that has the identical structure, make it work? It seems caused by the difference in thethrows
clause but I don't see why. Why is it different than passing an Object
off to a method and surrounding a call with a try/catch
?
推荐答案
您最初尝试 wrapConsumer
Consumer
作为参数,您尝试包装的lambda表达式仍然抛出异常
- 检查的异常。您的尝试
/ catch
距离抛出的异常太远,因为在创建lambda表达式的时候, ve在 Consumer
上创建了 消费者
的接受
方法 isn
Your initial attempt at wrapConsumer
didn't work because it still took a Consumer
as a parameter, and your lambda expression that you attempted to wrap still threw an Exception
-- a checked exception. Your try
/catch
is too far from the thrown exception, because at the point you create a lambda expression, you've created a Consumer
there, and Consumer
's accept
method isn't declared to throw any checked exceptions.
更改为接受 ConsumerWrapper
,因为该接口的方法声明允许它用 throws Exception
来抛出异常
。这允许你创建一个lambda表达式,引发一个检查异常。
The change to accepting a ConsumerWrapper
works because that interface's method declaration allows it to throw Exception
, with throws Exception
. That allows you to create a lambda expression that throws a checked exception.
这篇关于这些结构之间的区别是什么,一个不会编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!