JDK-8064316 : Incorrect thrown types inference in lambdas
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8,9
  • Priority: P4
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2014-11-07
  • Updated: 2017-09-06
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Related Reports
Relates :  
Description
Consider this source code:
---
public class Test {

    interface I1<E extends Throwable> {
        public void run() throws E;
    }

    public <E extends Throwable> void sink1(I1<E> i) throws E {
    }

    public void sink2(Runnable r) {
    }

    public void lambdaThrows() {
        try {
            throw new IllegalStateException();
        } catch (Throwable t) {
            sink1(() -> { throw t; }); //this does not compile, while all the other do
            sink1(() -> { });
            sink1(() -> { try { throw new IllegalStateException(); } catch (Throwable t2) { throw t2; } });
            sink2(() -> { throw t; });
        }
    }
}
---

The first call to "sink1" won't compile, because the inferred bound for E is "Throwable". But the inferred bound should be "IllegalStateException", and the code should compile.

The reason for this behavior is that when javac infers the bound, it only analyzes the effectively final and precise re-throw for the lambda's body, not for the surrounding code.