Why does a lambda change overloads when it throws a runtime exception?

前端 未结 5 1196
心在旅途
心在旅途 2021-01-31 02:14

Bear with me, the introduction is a bit long-winded but this is an interesting puzzle.

I have this code:

public class Testcase {
    public static void m         


        
5条回答
  •  独厮守ぢ
    2021-01-31 02:54

    First, according to §15.27.2 the expression:

    () -> { throw ... }
    

    Is both void-compatible, and value-compatible, so it's compatible (§15.27.3) with Supplier>:

    class Test {
      void foo(Supplier> bar) {
        throw new RuntimeException();
      }
      void qux() {
        foo(() -> { throw new IllegalArgumentException(); });
      }
    }
    

    (see that it compiles)

    Second, according to §15.12.2.5 Supplier (where T is a reference type) is more specific than Runnable:

    Let:

    • S := Supplier
    • T := Runnable
    • e := () -> { throw ... }

    So that:

    • MTs := T get() ==> Rs := T
    • MTt := void run() ==> Rt := void

    And:

    • S is not a superinterface or a subinterface of T
    • MTs and MTt have the same type parameters (none)
    • No formal parameters so bullet 3 is also true
    • e is an explicitly typed lambda expression and Rt is void

提交回复
热议问题