Summary
-------
According to the `JLS 24`, lambda expressions are compatible in an assignment context, invocation context, or casting context with a target type `T` if `T` is a functional interface type. Javac is allowing the type of lambda expressions to be classes in some cases. We are proposing fixing this issue by synchronizing the javac compiler with the `JLS 24`.
Problem
-------
Javac is not in sync with the `JLS 24`, in particular the Javac compiler is allowing the type of lambda expressions to be classes in some cases.
For example this code is accepted by javac:
class Test {
void m() {
Test r = (Test & Runnable) () -> System.out.println("Hello, World!");
}
}
here `Test&Runnable` is an intersection type but as we will see below in the referred specification sections a notional functional interface can't be induced from it as one of its components is a class different from `java.lang.Object`
Solution
--------
Synchronize the Javac compiler with the `JLS 24`. The compiler should not allow the type of lambda and method reference expressions to be classes.
Specification
-------------
This CSR is not proposing any specification change. But there is some normative specification text related to it. We are referring to section `§15.27.3 Type of a Lambda Expression` of the `JLS 24` in particular where it reads:
A lambda expression is compatible in an assignment context, invocation context,
or casting context with a target type T if T is a functional interface
type (§9.8) and the expression is congruent with the function type of the
ground target type derived from T .
Then from `§9.8 Functional Interfaces` we have that:
The declaration of a functional interface allows a functional interface type to be
used in a program. There are four kinds of functional interface type:
• An intersection type (§4.9) that induces a notional functional interface
On the other hand section `§4.9 Intersection Types` says:
Every intersection type T 1 & ... & T n induces a notional class or interface for the
purpose of identifying the members of the intersection type, as follows:
(...)
• If C k is Object , a notional interface is induced; otherwise, a notional class
is induced with direct superclass type C k . This class or interface has direct
superinterface types T 1 ', ..., T n ' and is declared in the package in which the
intersection type appears.