我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
我知道如何创建一个有String参数并返回int的方法的引用,它是:
Function<String, Integer>
然而,如果函数抛出异常,比如它被定义为:
Integer myMethod(String s) throws IOException
我该如何定义这个引用呢?
当前回答
默认情况下,Java 8函数不允许抛出异常,正如在多个回答中所建议的那样,有许多方法来实现它,其中一种方法是:
@FunctionalInterface
public interface FunctionWithException<T, R, E extends Exception> {
R apply(T t) throws E;
}
定义为:
private FunctionWithException<String, Integer, IOException> myMethod = (str) -> {
if ("abc".equals(str)) {
throw new IOException();
}
return 1;
};
并在调用者方法中添加抛出或尝试/捕获相同的异常。
其他回答
一些提供的解决方案使用E的泛型参数来传递抛出的异常类型。
更进一步,不是传递异常的类型,而是传递异常类型的Consumer,如……
Consumer<E extends Exception>
您可以创建几个Consumer<Exception>的可重用变体,这些变体将覆盖应用程序的常见异常处理需求。
免责声明:我还没有使用过Java 8,只是阅读过它。
Function<String, Integer>不抛出IOException,所以你不能在其中放入任何抛出IOException的代码。如果你正在调用一个期望Function<String, Integer>的方法,那么你传递给该方法的lambda不能抛出IOException,句号。你可以这样写一个lambda(我认为这是lambda语法,不确定):
(String s) -> {
try {
return myMethod(s);
} catch (IOException ex) {
throw new RuntimeException(ex);
// (Or do something else with it...)
}
}
或者,如果你传递lambda的方法是你自己写的,你可以定义一个新的函数接口,并使用它作为参数类型,而不是Function<String, Integer>:
public interface FunctionThatThrowsIOException<I, O> {
O apply(I input) throws IOException;
}
如果您不介意使用第三方库,使用cyclops-react(我贡献的一个库),您可以使用FluentFunctions API来编写
Function<String, Integer> standardFn = FluentFunctions.ofChecked(this::myMethod);
ofChecked接受jOOλ CheckedFunction,并将软化后的引用返回到标准(未选中)JDK java.util.function.Function。
或者,你可以通过FluentFunctions api继续使用捕获的函数!
例如,要执行你的方法,最多重试5次,并记录你可以写入的状态
FluentFunctions.ofChecked(this::myMethod)
.log(s->log.debug(s),e->log.error(e,e.getMessage())
.try(5,1000)
.apply("my param");
我会做一些一般的事情:
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());
您需要执行以下操作之一。
If it's your code, then define your own functional interface that declares the checked exception: @FunctionalInterface public interface CheckedFunction<T, R> { R apply(T t) throws IOException; } and use it: void foo (CheckedFunction f) { ... } Otherwise, wrap Integer myMethod(String s) in a method that doesn't declare a checked exception: public Integer myWrappedMethod(String s) { try { return myMethod(s); } catch(IOException e) { throw new UncheckedIOException(e); } } and then: Function<String, Integer> f = (String t) -> myWrappedMethod(t); or: Function<String, Integer> f = (String t) -> { try { return myMethod(t); } catch(IOException e) { throw new UncheckedIOException(e); } };