Inferring that what exceptions are thrown from a lambda

Esko Luontola esko.luontola at
Sat Aug 31 11:04:19 PDT 2013

Given an interface and method like this:

     public interface Action<T, E extends Throwable> {
         T run() throws E;

     public static <T, E extends Throwable> T tryRepeatedly(int 
maxTries, Action<T, E> action) throws E {
         // ...

If the method is provided a lambda that throws e.g. an IOException, the 
compiler figures out correctly that the method may also throw 
IOException and requires that exception to be rethrown:

     public void compiles() throws IOException {
         String result = Resilient.tryRepeatedly(10, () -> {
             throw new IOException("dummy exception");

But if the lambda doesn't thrown anything, the compiler thinks that the 
method may throw the most generic exception. The following code fails to 
compile with "error: unreported exception Throwable; must be caught or 
declared to be thrown"

     public void doesNotCompile() {
         String result = Resilient.tryRepeatedly(10, () -> "result");

So the developer must declare the surrounding method to throw an 
exception that may never be thrown:

     public void compilesButUndesirable() throws Throwable {
         String result = Resilient.tryRepeatedly(10, () -> "result");

Is this as planned or is it a bug? Is there a workaround? I would expect 
that since the compiler can figure out what exception the first case 
throws, it should also figure out that the latter case doesn't throw 
checked exceptions.

Esko Luontola

More information about the lambda-dev mailing list