我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
当前回答
我在课堂上遇到了这个问题。forName和Class。newInstance在lambda中,所以我做了:
public Object uncheckedNewInstanceForName (String name) {
try {
return Class.forName(name).newInstance();
}
catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
}
在lambda中,我没有调用Class.forName("myClass").newInstance(),而是调用uncheckedNewInstanceForName ("myClass")
其他回答
public void frankTest() {
int pageId= -1;
List<Book> users= null;
try {
//Does Not Compile: Object page=DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> new Portal(rw.getInt("id"), "", users.parallelStream().filter(uu -> uu.getVbid() == rw.getString("user_id")).findFirst().get(), rw.getString("name")));
//Compiles:
Object page= DatabaseConnection.getSpringConnection().queryForObject("SELECT * FROM bookmark_page", (rw, n) -> {
try {
final Book bk= users.stream().filter(bp -> {
String name= null;
try {
name = rw.getString("name");
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return bp.getTitle().equals(name);
}).limit(1).collect(Collectors.toList()).get(0);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return new Portal(rw.getInt("id"), "", users.get(0), rw.getString("name"));
} );
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
可以使用取消抛出包装器
Function<String, Integer> func1 = s -> Unthrow.wrap(() -> myMethod(s));
or
Function<String, Integer> func2 = s1 -> Unthrow.wrap((s2) -> myMethod(s2), s1);
这并不是Java 8所特有的。你正在尝试编译一些等价的东西:
interface I {
void m();
}
class C implements I {
public void m() throws Exception {} //can't compile
}
如果你有lombok,你可以用@SneakyThrows注释你的方法
SneakyThrow不会静默地吞咽、包装到RuntimeException中,或以其他方式修改所列出的检查异常类型的任何异常。JVM不检查被检查异常系统的一致性;Javac可以,而且这个注释允许您选择不使用它的机制。
https://projectlombok.org/features/SneakyThrows
这个问题也一直困扰着我;这就是我创建这个项目的原因。
用它你可以做:
final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;
JDK总共定义了39个接口,它们都有类似的抛出功能;这些都是流中使用的@ functionalinterface(基本流,还有IntStream, LongStream和DoubleStream)。
当它们中的每一个都扩展了它们的非抛出对应对象时,你也可以直接在lambdas中使用它们:
myStringStream.map(f) // <-- works
默认行为是,当您抛出lambda抛出一个检查异常时,抛出一个ThrownByLambdaException,并将检查异常作为原因。因此,您可以捕捉到它并得到原因。
其他特性也可用。