Search code examples
javalambdajava-8functional-interfacethrows

Method signature including the throws exception?


I know the method signature is including method name and its parameter list.

But how about throws Exception?

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

If it's not included then why I cannot pass in the following lambda:

() -> listServiceStatuses()

but I can pass in

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

And also I can throw it out again

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

I know the Supplier<T> functional interface, that's what really confusing me if throws is not part of the method signature.

Thanks for the help.


Solution

  • 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.

    But remember that "checked exception" means compile-time checked exception: the compiler makes sure that you have handled all checked exceptions; but once it has been compiled, checked and unchecked exception types are treated just the same. Notice that that the JVM spec doesn't even mention checkedness in the section on exceptions.

    So, as seen at runtime, the method can throw any exception. And as stated in the language spec:

    Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.