2009-12-15 10 views
77

Estoy tratando de aprender genéricos de Java. No tengo claro cuándo utilizará <T extends Foo> y cuándo usará <T super Foo>. ¿Qué significa cada una de estas cosas sobre T? Digamos que tengo <T extends Comparable> y <T super Comparable>, ¿qué significa cada uno de estos?cuál es la diferencia entre 'super' y 'extends' en Java Generics

He leído varios tutoriales en sun.com pero todavía estoy perdido. ¿Alguien puede ilustrar con ejemplos?

Gracias!

+0

esto se ha discutido antes - ver http://stackoverflow.com/questions/1368166/what-is-a-difference-between-super-e-and-extends-e y http://stackoverflow.com/questions/252055/java-generics-wildcards y http://stackoverflow.com/questions/1906677/super-e-and-extends-e-for-list – Adrian

+0

(Nota 'Comparable' es una tipo genérico, por lo que usarlo como un tipo sin formato en un límite genérico causará sufrimiento. Debería ser, al más "simple" ser 'Comparable '.) –

+6

no hay "", solo " " – newacct

Respuesta

15

Ver Effective Java 2ª edición, artículo 28:

PECS

P roducer e xtends, C onsumer s uper

Si el parámetro es una productor, debe ser <? extends T>, si es un consumidor tiene que ser <? super T>.

Tome un vistazo a las colecciones de Google, que saben cómo usarlo, porque consiguieron Bloch;)

+54

Esto realmente no explica cómo funcionan ni qué significan, mientras que [la respuesta de R Klatchko] (http : //stackoverflow.com/a/1911036/254477) hace. – ArtB

+9

No lo entiendo, no explica la diferencia. –

+9

Esta es la forma Bloch explica: _Suppose desea agregar métodos a granel to_ 'Pila ': • 'void pushAll (Colección src);' • 'void popAll (Colección DST);' • _user Can_ ' pushAll' _from a_ '' Colección _or a_ '' Colección _onto a_ '' Pila • _user Can_ 'popAll' _into a_' 'Colección _or a_ ' 'Colección _from a_' 'Pila 18446744073709551615

268

Depende de qué dirección permita la jerarquía de herencia. Supongamos que tiene una clase "Niño" que hereda de "Padre" que hereda de "Abuelo".

<T extends Parent> acepta padre o hijo, mientras que <T super Parent> acepta padre o abuelo.

+22

Esta es la mejor respuesta a esta pregunta que he visto, y debería ser el respuesta aceptada Simple y funciona a la perfección. – ArtB

+4

Así que es más parecido a heredar (extender) o subir la herencia (super) –

+0

acepta padre o abuelo, pero ¿qué hay de Child? Intenté agregar y acepta –

15

Hay tres tipos de comodines:

  • ? extends Type: Denota una familia de subtipos de tipo Type. Este es el comodín más útil.
  • ? super Type: denota una familia de supertipos del tipo Type.
  • ?: Denota el conjunto de todos los tipos o cualquiera.
+22

FYI: esto se extrae de http://java.sun.com/developer/technicalArticles/J2SE/generics/ En el futuro, mencione sus fuentes en lugar de escribir como si fueran suyas. – BalusC

+0

El enlace de @ BalusC al artículo ya no funciona. Aquí está uno actual: http://www.oracle.com/technetwork/articles/javase/generics-136597.html – Dathan

4

Si está preguntando acerca de los parámetros de tipo, entonces no existe la construcción <T super X> en Java. El parámetro delimitado solo puede extend, pero puede extender más de un tipo. Por ejemplo

public class MyClass< T extends Closeable & Runnable > 
{ 
    // Closeable and Runnable are chosen for demonstration purposes only 
} 

En este caso, si ves a continuación MyClass<ConcreteT> concretet debe declararse como

public class ConcreteT 
    implements Closeable, Runnable 
{ 
    ... 
} 

Para comodines acotadas, leer this article. Lea la sección en get-put principle. Básicamente, super corresponde a la semántica write, y extends corresponde a la semántica read.

13

Para mí, la mejor respuesta vino de @BSingh, cuando leí el artículo de Uncle Bob. Vuelvo aquí, la conclusión del artículo.

Usar lista < T súper Traje> cada vez que se va a escribir en la lista.

Cuando coloca un objeto en la lista, lo único que importa es que el objeto sea de un tipo que sea compatible con el tipo de la lista. Así que desea que la lista tome el tipo de ese objeto o cualquiera de las superclases de ese objeto.

Usar lista < T extiende Traje> cada vez que se va a leer de una lista.

Por otro lado, cuando lee de una lista, quiere que el tipo que está leyendo sea del tipo que figura en la lista, o un derivado de ese tipo.

Cuestiones relacionadas