我知道如何创建一个有String参数并返回int的方法的引用,它是:

Function<String, Integer>

然而,如果函数抛出异常,比如它被定义为:

Integer myMethod(String s) 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");

其他回答

如果你不介意使用第三方自由库(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的创造者。

一些提供的解决方案使用E的泛型参数来传递抛出的异常类型。

更进一步,不是传递异常的类型,而是传递异常类型的Consumer,如……

Consumer<E extends Exception>

您可以创建几个Consumer<Exception>的可重用变体,这些变体将覆盖应用程序的常见异常处理需求。

我所做的是允许用户在异常情况下给出他实际想要的值。 我有一个像这样的东西

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)

这个问题也一直困扰着我;这就是我创建这个项目的原因。

用它你可以做:

final ThrowingFunction<String, Integer> f = yourMethodReferenceHere;

JDK总共定义了39个接口,它们都有类似的抛出功能;这些都是流中使用的@ functionalinterface(基本流,还有IntStream, LongStream和DoubleStream)。

当它们中的每一个都扩展了它们的非抛出对应对象时,你也可以直接在lambdas中使用它们:

myStringStream.map(f) // <-- works

默认行为是,当您抛出lambda抛出一个检查异常时,抛出一个ThrownByLambdaException,并将检查异常作为原因。因此,您可以捕捉到它并得到原因。

其他特性也可用。

这并不是Java 8所特有的。你正在尝试编译一些等价的东西:

interface I {
    void m();
}
class C implements I {
    public void m() throws Exception {} //can't compile
}