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 superinterfaceComparator<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
orstatic
methods from its superinterface types.
JLS 9.4.1:
An interface does not inherit
private
orstatic
methods from its superinterfaces.
- csr of
-
JDK-8365676 javac incorrectly allows calling interface static method via type variable
-
- In Progress
-