方法签名包括抛出异常?

时间:2018-05-21 12:07:52

标签: java lambda java-8 functional-interface throws

我知道方法签名包含方法名称及其参数列表

throws Exception怎么样?

public List<ServiceStatusVo> listServiceStatuses() throws RetrieverException {
    ...
    return list;
}

如果没有包含,那么为什么无法传递以下lambda:

() -> listServiceStatuses()

但我可以传入

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
    }
}

我也可以再次

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
        throw e;
    }
}

我知道Supplier<T>功能界面,如果 抛出不是方法签名的一部分,那就是让我感到困惑的

感谢您的帮助。

1 个答案:

答案 0 :(得分:4)

这不是关于方法签名的直接。来自JLS Sec 11.2.3

  

如果一个lambda体可以抛出一些异常类E,当E是已检查的异常并且 E 不是子类时,这是一个编译时错误在lambda表达式所针对的函数类型的throws子句中声明的某个类。

这有点令人惊讶 - 我必须承认我最初的想法是异常方法签名的一部分。

但请记住,“检查异常”意味着compile-time checked exception:编译器确保您已处理所有已检查的异常;但是一旦编译完成,检查和未检查的异常类型将被视为相同。请注意,the JVM spec甚至没有在关于例外的部分中提及检查。

因此,正如在运行时看到的,该方法可以抛出任何异常。正如语言规范中所述:

  

两个方法或构造函数M和N具有相同的签名,如果它们具有相同的名称,相同的类型参数(如果有的话)(第8.4.4节),并且在将形式参数类型N调整为M的类型参数,相同的形式参数类型。