带有通用异常的lamda的类型推断选择Exception而不是RuntimeException?

时间:2019-04-17 10:30:47

标签: java generics lambda

以下SSCCE显示了我当前正在尝试的操作:我想编写一个使用用户定义的lambda并稍后执行的API。 lambda定义了通用异常类型,因此用户可以指定可能引发的自定义异常。

到目前为止,很好,这是API部分的代码:

public class Api {

  interface ThrowingLambda<E extends Exception> {
    public void doSomething() throws E;
  }

  static class Delegator<E extends Exception> {

    private ThrowingLambda<E> function;

    public Delegator(ThrowingLambda<E> function) {
      this.function = function;
    }

    public void doSomething() throws E {
      function.doSomething();
    }
  }

  public static <E extends Exception> Delegator<E> takeAlambda(ThrowingLambda<E> function) {
    return new Delegator<E>(function);
  }

}

上面的代码可以编译,这里没有错。但是,如果使用API​​的客户端指定了不声明任何异常的lambda,则现在会遇到问题:

import org.junit.Test;

public class TestApi {

  @Test
  public void shouldCompile() {
    Api.takeAlambda(TestApi::doSomething)
        .doSomething();
  }

  public static void doSomething() {
    System.out.println("Did something!");
  }

}

从我的角度来看,我希望编译器为lambda的异常类型推断类型RuntimeException。 Eclipse编译器可以做到这一点,并且一切似乎都很好,但是Java编译器却认为与众不同,并大吃一惊:

[ERROR] COMPILATION ERROR : 
TestApi.java:[10,21] unreported exception java.lang.Exception; must be caught or declared to be thrown
[INFO] 1 error

更有趣的是:如果将throws E添加到方法takeAlambda(ThrowingLambda<E> function)中,则它将起作用,并且编译器不再抱怨。

我不知道编译器在这里做什么。这是编译器错误还是故意的?

1 个答案:

答案 0 :(得分:0)

看起来像Java 1.8_191中的错误。它可以在Java 11中使用。我不知道版本<11。