Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8354304

Lambda expression types can't be classes

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P3 P3
    • 25
    • tools
    • None
    • source
    • minimal
    • Hide
      Although the Javac compiler could have been accepting incorrect code based on the related bug, the compiled classes were rejected by the the verifier at execution time. So it would be practically impossible to affect production code with the change proposed in this CSR
      Show
      Although the Javac compiler could have been accepting incorrect code based on the related bug, the compiled classes were rejected by the the verifier at execution time. So it would be practically impossible to affect production code with the change proposed in this CSR
    • Language construct
    • SE

      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

            vromero Vicente Arturo Romero Zaldivar
            webbuggrp Webbug Group
            Chen Liang, Jan Lahoda
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: