为什么 Java 8 类型推断不考虑 Lambda 在重载选择中引发的异常?
我有一个关于Java 8推理的问题,关于lambda及其相关的异常签名。
如果我定义一些方法 foo:
public static <T> void foo(Supplier<T> supplier) {
//some logic
...
}
然后我得到了一个漂亮而简洁的语义,能够在大多数情况下为给定的.但是,在此示例中,如果我的操作声明它,则我采用 Supplier 的方法不再编译:Supplier 方法签名不会引发异常。foo(() -> getTheT());
T
getTheT
throws Exception
foo
get
似乎解决这个问题的一个体面的方法是重载foo接受任何一个选项,重载的定义是:
public static <T> void foo(ThrowingSupplier<T> supplier) {
//same logic as other one
...
}
其中 ThrowingSupplier 被定义为
public interface ThrowingSupplier<T> {
public T get() throws Exception;
}
通过这种方式,我们有一个会引发异常的供应商类型,另一个不会引发异常。所需的语法将如下所示:
foo(() -> operationWhichDoesntThrow()); //Doesn't throw, handled by Supplier
foo(() -> operationWhichThrows()); //Does throw, handled by ThrowingSupplier
但是,由于 lambda 类型不明确(可能无法在 Supplier 和 ThrowingSupplier 之间解决),这会导致问题。做一个显式的转换 la 会起作用,但它摆脱了所需语法的大部分简洁性。foo((ThrowingSupplier)(() -> operationWhichThrows()));
我想潜在的问题是:如果Java编译器能够解决我的一个lambda不兼容的事实,因为它在仅限供应商的情况下抛出异常,为什么它不能使用相同的信息来派生辅助类型推断情况下的lambda类型?
任何人都可以向我指出的任何信息或资源同样非常感谢,因为我不太确定在哪里寻找有关此事的更多信息。
谢谢!