Inferring that what exceptions are thrown from a lambda

Esko Luontola esko.luontola at gmail.com
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
www.orfjackal.net


More information about the lambda-dev mailing list