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.
Note
Any binary produced by javac because of this lack of sync with the JLS is rejected by the verifier at execution time
- csr of
-
JDK-8322810 Lambda expression types can't be classes
-
- In Progress
-