2

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.

Hearen
  • 7,420
  • 4
  • 53
  • 63
  • 1
    Seems like you've answered your own question, no? Supplier.get() does not throw any checked exceptions, so a lambda that throws a checked exception would not conform to the required type. – jspcal May 21 '18 at 12:11
  • @jspcal I just feel it that way, but till now I did not find out any official doc to specify it. Would you provide some details? – Hearen May 21 '18 at 12:12
  • Fully described hire http://www.baeldung.com/java-lambda-exceptions – Victor Gubin May 21 '18 at 12:12
  • @VictorGubin I know that post describing how to handle this case, but what I wanna know here is **why**? – Hearen May 21 '18 at 12:18
  • @Hearen I do believe it is all about [no side effect](https://en.wikipedia.org/wiki/Side_effect_(computer_science)) [functional programming](https://en.wikipedia.org/wiki/Functional_programming) idiom. Exception racing is really - a side effect. Lambdas is an idea from functional programming added to imperative language as an addition. – Victor Gubin May 21 '18 at 12:23
  • 2
    @VictorGubin not really, there is nothing to stop a lambda throwing a checked exception (e.g. `interface CheckedSupplier { T get() throws E; }`); you just can't throw it for the `Supplier` type. – Andy Turner May 21 '18 at 12:25

1 Answers1

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.

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.

Hearen
  • 7,420
  • 4
  • 53
  • 63
Andy Turner
  • 137,514
  • 11
  • 162
  • 243