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

javac incorrectly allows calling interface static method via type variable

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • tools
    • None
    • source
    • low
    • Some code will stop compiling, but migration is trivial. Existing binary already compile down to the correct invokestatic on interface methodref, so there is no binary compatibility concern.
    • Language construct
    • Implementation

      Summary

      javac now rejects calling interface static methods through a type variable if the interface is the only upper bound of the type variable.

      Problem

      javac incorrectly allowed interface static methods to be resolved against type variable if the interface is the only upper bound of the type variable.

      JLS 4.4 and 4.9 together indicates that the members of such a type variable is a notional interface introduced with that only upper bound interface as its only direct superinterface. Meanwhile, JLS 9.4.1 (and 8.4.8) indicates static methods are never inherited from superinterfaces. In conclusion, such interface static methods are not present on such a type variable.

      Currently in javac, for interface java.util.Comparator<Object>, and a static method Comparator::reverseOrder, these are the resolution behaviors:

      • For type variable T extends Comparator<Object>, T.reverseOrder() succeeds;
      • For type variable T extends Object & Comparator<Object>, T.reverseOrder() fails;
      • For class java.text.Collator which has a direct superinterface Comparator<Object>, Collator.reverseOrder() fails;

      Since Collator is a valid type argument for both previous type variables T, we should reject all interface static method resolution on type variables.

      Solution

      Reject such interface static method resolutions in javac with a "cannot resolve" message for compiling against all previous releases, because the behavior in the example above applies for all releases.

      Existing bytecode will continue to work.

      Users can easily migrate by using the explicit interface identifier to resolve the static methods instead.

      Specification

      No change.

      JLS 4.4:

      The members of a type variable X with bound T & I1 & ... & In are the members of the intersection type (ยง4.9) T & I1 & ... & In appearing at the point where the type variable is declared.

      JLS 4.9:

      If Ck is Object, a notional interface is induced; otherwise, a notional class is induced with direct superclass type Ck. This class or interface has direct superinterface types T1', ..., Tn' and is declared in the package in which the intersection type appears.

      The members of an intersection type are the members of the class or interface it induces.

      JLS 8.4.8:

      A class does not inherit private or static methods from its superinterface types.

      JLS 9.4.1:

      An interface does not inherit private or static methods from its superinterfaces.

            liach Chen Liang
            webbuggrp Webbug Group
            Vicente Arturo Romero Zaldivar
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: