方法签名包括抛出异常?

Hea*_*ren 1 java lambda throws java-8 functional-interface

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

但是throws Exception呢?

public List<ServiceStatusVo> listServiceStatuses() throws RetrieverException {
    ...
    return list;
}
Run Code Online (Sandbox Code Playgroud)

如果不包括在内,那么为什么我不能传入以下 lambda:

() -> listServiceStatuses()
Run Code Online (Sandbox Code Playgroud)

但我可以通过

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
    }
}
Run Code Online (Sandbox Code Playgroud)

我也可以再次扔掉

() -> {
    try {
        return listServiceStatuses();
    } catch (RetrieverException e) {
        throw e;
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道Supplier<T>函数式接口,如果 throws不是方法签名的一部分,那真的让我感到困惑。

谢谢您的帮助。

And*_*ner 5

It's not about the method signature directly. From JLS Sec 11.2.3:

It is a compile-time error if a lambda body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the function type targeted by the lambda expression.

This is a little surprising - I must admit that my initial thought was that the exception is part of the method signature.

但请记住,“检查异常”意味着编译时检查异常:编译器确保您已处理所有检查异常;但是一旦它被编译,已检查和未检查的异常类型的处理方式是一样的。请注意,JVM 规范在异常部分甚至没有提到检查性。

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

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