The following SSCCE shows what I'm currently trying: I want to write an API that takes a user-defined lambda and executes it later on. The lambda defines a generic exception type, so the user may specify a custom exception that may be thrown.

So far, so good, here is the code of the API part:

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);
  }

}

The above code compiles, nothing wrong here. But the client that is using the API now gets a problem if he specifies a lambda that does not declare any exceptions:

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!");
  }

}

From my point of view I would expect the compiler to infere the type RuntimeException for the lambda's exception type. The Eclipse compiler does this and everything seems to be fine, but the Java compiler thinks different and goes bananas:

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

Even more funny: If you add throws E to the method takeAlambda(ThrowingLambda<E> function) then it works and the compiler does not complain anymore.

I've no idea what the compiler does here. Is this a compiler bug or something that is on purpose?

1 Answers

0
UNIQUEorn On Best Solutions

Seems like a bug in Java 1.8_191. It works with Java 11. I don't know about versions < 11.