我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
当前回答
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();
}
}
其他回答
我是一个小库的作者,它具有一些通用的魔法,可以在任何地方抛出任何Java异常,而不需要捕获它们,也不需要将它们包装到RuntimeException中。
用法: unchecked(() -> methodThrowingCheckedException())
public class UncheckedExceptions {
/**
* throws {@code exception} as unchecked exception, without wrapping exception.
*
* @return will never return anything, return type is set to {@code exception} only to be able to write <code>throw unchecked(exception)</code>
* @throws T {@code exception} as unchecked exception
*/
@SuppressWarnings("unchecked")
public static <T extends Throwable> T unchecked(Exception exception) throws T {
throw (T) exception;
}
@FunctionalInterface
public interface UncheckedFunction<R> {
R call() throws Exception;
}
/**
* Executes given function,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* @return result of function
* @see #unchecked(Exception)
*/
public static <R> R unchecked(UncheckedFunction<R> function) {
try {
return function.call();
} catch (Exception e) {
throw unchecked(e);
}
}
@FunctionalInterface
public interface UncheckedMethod {
void call() throws Exception;
}
/**
* Executes given method,
* catches and rethrows checked exceptions as unchecked exceptions, without wrapping exception.
*
* @see #unchecked(Exception)
*/
public static void unchecked(UncheckedMethod method) {
try {
method.call();
} catch (Exception e) {
throw unchecked(e);
}
}
}
来源:https://github.com/qoomon/unchecked-exceptions-java
实际上,您可以使用一个处理异常的新接口来扩展Consumer(和Function等)——使用Java 8的默认方法!
考虑这个接口(扩展Consumer):
@FunctionalInterface
public interface ThrowingConsumer<T> extends Consumer<T> {
@Override
default void accept(final T elem) {
try {
acceptThrows(elem);
} catch (final Exception e) {
// Implement your own exception handling logic here..
// For example:
System.out.println("handling an exception...");
// Or ...
throw new RuntimeException(e);
}
}
void acceptThrows(T elem) throws Exception;
}
然后,例如,如果你有一个列表:
final List<String> list = Arrays.asList("A", "B", "C");
如果你想消费它(例如。使用forEach)和一些抛出异常的代码,你通常会设置一个try/catch块:
final Consumer<String> consumer = aps -> {
try {
// maybe some other code here...
throw new Exception("asdas");
} catch (final Exception ex) {
System.out.println("handling an exception...");
}
};
list.forEach(consumer);
但是有了这个新接口,你可以用lambda表达式实例化它,编译器不会报错:
final ThrowingConsumer<String> throwingConsumer = aps -> {
// maybe some other code here...
throw new Exception("asdas");
};
list.forEach(throwingConsumer);
或者甚至只是转换它更简洁!:
list.forEach((ThrowingConsumer<String>) aps -> {
// maybe some other code here...
throw new Exception("asda");
});
更新
看起来榴莲有一个非常好的实用程序库,叫做Errors,可以用来解决这个问题,具有更大的灵活性。例如,在上面的实现中,我显式地定义了错误处理策略(System.out…或者抛出RuntimeException),而Durian的Errors允许您通过一套大型实用程序方法动态应用策略。感谢分享,@NedTwigg!
示例用法:
list.forEach(Errors.rethrow().wrap(c -> somethingThatThrows(c)));
如果你不介意使用第三方自由库(Vavr),你可以写
CheckedFunction1<String, Integer> f = this::myMethod;
它也有所谓的Try单子来处理错误:
Try(() -> f.apply("test")) // results in a Success(Integer) or Failure(Throwable)
.map(i -> ...) // only executed on Success
...
请在这里阅读更多。
声明:我是Vavr的创造者。
我会做一些一般的事情:
public interface Lambda {
@FunctionalInterface
public interface CheckedFunction<T> {
T get() throws Exception;
}
public static <T> T handle(CheckedFunction<T> supplier) {
try {
return supplier.get();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
}
}
用法:
Lambda.handle(() -> method());
我所做的是允许用户在异常情况下给出他实际想要的值。 我有一个像这样的东西
public static <T, R> Function<? super T, ? extends R> defaultIfThrows(FunctionThatThrows<? super T, ? extends R> delegate, R defaultValue) {
return x -> {
try {
return delegate.apply(x);
} catch (Throwable throwable) {
return defaultValue;
}
};
}
@FunctionalInterface
public interface FunctionThatThrows<T, R> {
R apply(T t) throws Throwable;
}
这个可以被称为:
defaultIfThrows(child -> child.getID(), null)