106 votos

Java Generics (comodines)

Tengo un par de preguntas sobre Java genérica comodines:

  1. ¿Cuál es la diferencia entre List<? extends T> yList<? super T>

  2. ¿Qué es un comodín limitado y lo que es un comodín de ilimitada?

120voto

Bill the Lizard Puntos 147311

En su primera pregunta, <? extends T> y <? super T> son ejemplos de limitada comodines. Una desenfrenada comodín se ve como <?>, y significa básicamente <? extends Object>. Libremente significa que el genérico puede ser de cualquier tipo. Un almacén de comodín (<? extends T> o <? super T>) coloca una restricción en el tipo diciendo que se tiene que extender un tipo específico (<? extends T> es conocido como un límite superior), o tiene que ser un antepasado de un tipo específico (<? super T> es conocido como un límite inferior).

Los Tutoriales de Java tienen algunas muy buenas explicaciones de los genéricos en los artículos Comodines y Más Diversión con los Comodines.

49voto

oxbow_lakes Puntos 70013

Si usted tiene una jerarquía de clases A, B es una subclase de la A y C y D son subclase de B como abajo

class A {}
class B extends A {}
class C extends B {}
class D extends B {}

Entonces

List<? extends A> la;
la = new ArrayList<B>();
la = new ArrayList<C>();
la = new ArrayList<D>();

List<? super B> lb;
lb = new ArrayList<A>(); //fine
lb = new ArrayList<C>(); //will not compile

public void someMethod(List<? extends B> lb) {
    B b = lb.get(0); // is fine
    lb.add(new C()); //will not compile as we do not know the type of the list, only that it is bounded above by B
}

public void otherMethod(List<? super B> lb) {
    B b = lb.get(0); // will not compile as we do not know whether the list is of type B, it may be a List<A> and only contain instances of A
    lb.add(new B()); // is fine, as we know that it will be a super type of A 
}

Un comodín limitado es como ? extends B donde B es un tipo. Es decir, el tipo es desconocido pero puede colocarse un "salto" en él. En este caso, está limitado por una clase, que es una subclase de B.

39voto

blank Puntos 7947

Josh Bloch también tiene una buena explicación de cuándo usar super y extends en esta google io vídeo de la charla donde se menciona el Productor extends Consumo super mnemónico.

A partir de las diapositivas de la presentación:

Suponga que desea agregar a granel métodos para Stack<E>

void pushAll(Collection<? extends E> src);

- src es un Correo del productor

void popAll(Collection<? super E> dst);

- horario de verano es de un Correo al consumidor

7voto

Ted Gao Puntos 81

Usted puede encontrar mi tutorial sobre este tema mucho más profundo y provechoso.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by: