Eclipse ECJ accepts this code, javac does not - who is right?

Consider the following function returnsNulland call it with a common type:

public static <T> List<T> returnNull(Class<? extends T> clazz) {
    return null;
}

public static void main( String[] args )
{
    List<AtomicReference<?>> l = returnNull(AtomicReference.class);
}

The Eclipse compiler, when installed on Java 8, accepts it, but javacrejects it in Java 8 with:

incompatible types: cannot infer type-variable(s) T
    (argument mismatch; java.lang.Class<java.util.concurrent.atomic.AtomicReference> cannot be converted to java.lang.Class<? extends java.util.concurrent.atomic.AtomicReference<?>>)

The main difference is that, given the two parameterized types P1<T>, P2<T>Eclipse allows conversion from the external type parameterized by the original internal type: P1<P2>to the external type, the lower type parameterized by the lower bound, with an unlimited wildcard, for example P1<? extends P2<?>>. javacdoes not work.

This is not just a theoretical reflection: if this code were accepted, it would solve my generics filtering problem .

Who is right?

+5
1

ECJ <T> AtomicReference#RAW, returnNull

List<AtomicReference#RAW> returnNull(Class<? extends AtomicReference#RAW>)

:

  • :
    • ⟨Class<AtomicReference#RAW> → Class<? extends T#0>⟩
  • :
    • ⟨Class<AtomicReference#RAW> <: Class<? extends T#0>⟩
    • ⟨AtomicReference#RAW <=? extends T#0⟩
    • ⟨AtomicReference#RAW <: T#0⟩
    • AtomicReference#RAW <: T#0
  • :
    • T#0 = AtomicReference#RAW

Class<AtomicReference#RAW> .

(#RAW - , ).

: - : , ( ) :

  • ⟨AtomicReference#RAW <: AtomicReference<?>⟩

FALSE, ecj - TRUE. , .

528970 ECJ.

, javac , - T#RAW <: T<X>. ECJ , , , : javac , ECJ .

2: , ECJ , JLS JDK-8054721 .

+4

Source: https://habr.com/ru/post/1690290/


All Articles