java - 为什么 Java 1.8 中的函数式接口(interface)(Function、Supplier、Consumer 等)不会抛出泛型异常?

标签 java lambda java-8

我必须定义自己的可抛出功能接口(interface),例如

@FunctionalInterface
public interface ConsumerEx<T, E extends Exception> {
    public void accept(T t) throws E;

    public default ConsumerEx<T, E> andThen(ConsumerEx<? super T, ? extends E> after) {
        return t -> {
            accept(t);
            after.accept(t);
        };
    }
}

但它不能与 forEach 一起使用:-(

最佳答案

功能接口(interface)是通用接口(interface)。但是,具有通用异常的接口(interface)只能在特殊上下文中工作,在该上下文中,您将实例传递给方法,该方法将立即调用该函数并重新抛出异常。

但是,它在任何不立即调用该函数的上下文中都不起作用,例如当它在不同的线程中执行或稍后执行时。

你的特殊消费者正是这样的场景,行不通。您无法编写一个普通的 Consumer 来委托(delegate)给 ConsumerEx 实例并准确捕获为特定 ConsumerEx 实例声明的异常。由于类型删除,您不知道 E 的确切类型。尝试将捕获的异常包装在专门的包装器 RuntimeException 中会更加困难。包装器异常必须是类型参数与 E 匹配的通用异常,但您无法捕获具有类型参数的通用异常。

如果函数接口(interface)允许通用异常类型,这些问题与 JRE 开发人员在并行流执行时面临的问题完全相同。终端操作不可能保证只重新抛出已声明的已检查通用异常。

关于java - 为什么 Java 1.8 中的函数式接口(interface)(Function、Supplier、Consumer 等)不会抛出泛型异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28495504/

相关文章:

java: 如何在 jboss 平台中对用户隐藏 html 和图像等静态资源?

JavaScript:如何处理所有后续的元素对?

c++ - 区分黑白捕获的 `this` 成员与 C++ lambda 中捕获的变量

c# - 如何异步设置委托(delegate)类型 UITextField.ShouldReturn?

java - 使用自定义比较器查找数组列表的最大值

Java新手: Swing and displaying ASCII files

java - 如何检测外部 Java 应用程序中的按钮何时被按下?

java - 如何使用 Java 在 Mac Keychain 中存储用户名/密码?

iterator - Java 8 迭代器流到迭代器会导致对 hasNext() 的冗余调用

java-8 - FreeMarker Java 8 可选值支持