Este es un pequeño fragmento de código tomado de algunos de los ejemplos que acompañan al Stanford Parser. He estado desarrollando en Java durante aproximadamente 4 años, pero nunca he tenido una comprensión muy sólida de lo que se supone que indica este estilo de código.
List<? extends HasWord> wordList = toke.tokenize();
No me preocupan los detalles del código. Lo que me confunde es qué se supone que debe transmitir exactamente la expresión genérica, en inglés.
¿Alguien puede explicarme esto?
Respuestas:
significa "Una clase / interfaz que se extiende
HasWord
". En otras palabras,HasWord
sí mismo o cualquiera de sus hijos ... básicamente cualquier cosa que funcione coninstanceof HasWord
plusnull
.En términos más técnicos,
? extends HasWord
es un comodín acotado, cubierto en el Artículo 31 de Effective Java 3rd Edition , que comienza en la página 139. El mismo capítulo de la 2da Edición está disponible en línea como PDF ; la parte de los comodines delimitados es el Artículo 28 que comienza en la página 134.Actualización: el enlace PDF se actualizó desde que Oracle lo eliminó hace un tiempo. Ahora apunta a la copia presentada por la Escuela de Ingeniería Electrónica e Informática de la Universidad Queen Mary de Londres.
Actualización 2: Veamos un poco más de detalles sobre por qué querría usar comodines.
Si declara un método cuya firma espera que pase
List<HasWord>
, entonces lo único que puede pasar es aList<HasWord>
.Sin embargo, si dicha firma era,
List<? extends HasWord>
entonces podría pasar un en suList<ChildOfHasWord>
lugar.Tenga en cuenta que hay una sutil diferencia entre
List<? extends HasWord>
yList<? super HasWord>
. Como dijo Joshua Bloch: PECS = productor-se extiende, consumidor-super.Lo que esto significa es que si está pasando una colección de la cual su método extrae datos (es decir, la colección está produciendo elementos para su método), debe usarla
extends
. Si está pasando una colección a la que su método agrega datos (es decir, la colección está consumiendo elementos que crea su método), debe usarlasuper
.Esto puede sonar confuso. Sin embargo, puede verlo en
List
elsort
comando de (que es solo un acceso directo a la versión de dos argumentos de Collections.sort). En lugar de tomar unComparator<T>
, en realidad se necesita unComparator<? super T>
. En este caso, el Comparador está consumiendo los elementos delList
para reordenar la Lista misma.fuente
List<HasWord>
es exactamente lo que usted describe: una lista que contiene cualquier objetox
para el cualx instanceof HasWord
devuelve verdadero, ynull
. No necesitas un comodín para esto. El comodín significa que en realidad también puede ser una lista de otro tipo, siempre que este tipo sea un subtipo deHasWord
. (Perdón por el comentario tardío.)Un signo de interrogación es un significante para 'cualquier tipo'.
?
solo significamientras su ejemplo anterior significa
fuente
public Set<Class<?>> getClasses()
significa? ¿Cuál es la diferencia conSet<Class>
? Estoy mirandojavax.ws.rs.core.Application
.List<? extends HasWord>
acepta cualquier clase concreta que extienda HasWord. Si tienes las siguientes clases ...... la
wordList
lata SOLO puede contener una lista de As o Bs o una mezcla de ambas porque ambas clases extienden el mismo padre onull
(que falla la instancia de las comprobacionesHasWorld
).fuente
List<? extends Collection<String>> list = new ArrayList<List<String>>();
.List<HasWord>
funciona igual de bien para esto. El punto aquí es que esta variable puede contener aoList<A>
oList<B>
aList<HasWord>
.Quizás un ejemplo artificial del "mundo real" ayudaría.
En mi lugar de trabajo tenemos contenedores de basura que vienen en diferentes sabores. Todos los contenedores contienen basura, pero algunos contenedores son especializados y no toman todo tipo de basura. Entonces tenemos
Bin<CupRubbish>
yBin<RecylcableRubbish>
. El sistema de tipos necesita asegurarse de que no puedo colocar miHalfEatenSandwichRubbish
en ninguno de estos tipos, pero puede ir a un contenedor de basura generalBin<Rubbish>
. Si quisiera hablar sobre unoBin
de losRubbish
cuales puede estar especializado para no poder poner basura incompatible, entonces seríaBin<? extends Rubbish>
.(Nota:
? extends
no significa solo lectura. Por ejemplo, con las precauciones adecuadas puedo sacar un pedazo de basura de un contenedor de especialidad desconocida y luego volver a colocarlo en un lugar diferente).No estoy seguro de cuánto ayuda eso. Puntero a puntero en presencia de polimorfismo no es del todo obvio.
fuente
En inglés:
En general, el término
?
genérico significa cualquier clase. Yextends SomeClass
especifica que ese objeto debe extenderseSomeClass
(o ser esa clase).fuente
El signo de interrogación se utiliza para definir comodines . Consulte la documentación de Oracle sobre ellos: http://docs.oracle.com/javase/tutorial/java/generics/wildcards.html
fuente