Código compilar con el eclipse, pero no con javac

SceDev:

El siguiente código compila sin ningún error con Eclipse, pero genera un error con javac. Parece ser un error de compilación, pero no sé cuál es el adecuado.

Me gustaría señalar que sé cómo corregir este error al cambiar el código para que funcione con ambos, pero ese no es el tema actual. Me gustaría saber si es un java o un problema eclipse.

Trato con IntelliJ pero tengo el mismo error javac.

Código de ejemplo para reproducir este error:

import java.util.ArrayList;
import java.util.List;

public class A<T extends B> {
    protected List<C> list = new ArrayList<>();

    class C {}

    public void createIO() {
        A<? extends B> x = null;
        List<A<? extends B>.C> y = x.list;
    }
}

class B {
}

JVM:

openjdk version "13-BellSoft" 2019-09-17
OpenJDK Runtime Environment (build 13-BellSoft+33)
OpenJDK 64-Bit Server VM (build 13-BellSoft+33, mixed mode, sharing)

Con Eclipse, no tengo ningún error. Con javac, tengo el error :

A.java:13: error: incompatible types: List<A<CAP#1>.C> cannot be converted to List<A<? extends B>.C>
        List<A<? extends B>.C> y = x.list;
                                    ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends B from capture of ? extends B
Oleksandr Pyrohov:

El compilador de Eclipse debe mostrar un error de compilación, como javaclo hace. Ver Eclipse bug 539105 .

javaccomportamiento es correcta y está alineado con los JLS :

Y si una clase genérica C<T>tiene una clase de miembro no genérico D, entonces el tipo de miembro C<String>.Des un tipo parametrizado, a pesar de que la clase Dno es genérica.

Por lo tanto, a pesar de que la clase interna Cno es genérica, el:

A<? extends B>.C

es un tipo parametrizado , donde el parámetro de tipo de Aes un desconocido subtipo de B. Por lo tanto, todas las normas sobre los genéricos se aplican a Ctan bien en este contexto.

Por lo tanto, para eliminar el error del compilador, el tipo de ypuede ser declarado de la siguiente manera:

List<? extends A<? extends B>.C> y = x.list;

Pero hay que tener en cuenta que esto no permitirá añadir elementos a la lista y(ver PECS ).

Si suena complicado, trate de pensar en ello en el alcance de un ejemplo simplificado:

List<Integer> l1 = new ArrayList<>();
List<Number > l2 = l1; // Error: incompatible types...

List<? extends Number> l3 = l1; // OK

Detalles adicionales:

El ejemplo de la pregunta puede ser minimizado a:

class A<T> {
    class C {}
    List<C> l1 = null;
    List<A<?>.C> l2 = l1; // Error: incompatible types...
    List<? extends A<?>.C> l3 = l1; // OK
}

List<A<?>.C>es una lista de Cde Ade tipo desconocido; Cde arbitraria Apuede ser añadido:

class A<T> {
    class C {}
    C c = new C();
    void foo(List<A<?>.C> list) {
        list.add(new A<String>().c);
        list.add(new A<Number>().c);
    }
}

Ver también:

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=331997&siteId=1
Recomendado
Clasificación