wildcards type parameter method lower generic bound java generics bounded-wildcard

type - Comodines ilimitados en Java



java wildcard capture (6)

¿Hay alguna vez una diferencia entre un comodín ilimitado, por ejemplo, <?> Y un comodín delimitado cuyo límite es Object , por ejemplo, <? extends Object> <? extends Object> ?

Recuerdo haber leído en alguna parte que había una diferencia en los primeros borradores de los genéricos, pero que ya no puedo encontrar esa fuente.


Como punto de vista, hay una diferencia si la clase / interfaz / constructor / método declara un límite (que no sea extends Object ).

interface Donkey<T extends Thing> { } ... Donkey<? extends Object> foo; // FAIL


De la experimentación parece que, por ejemplo, List<?> Y List<? extends Object> List<? extends Object> son compatibles con la asignación en ambos sentidos, y un método que tiene una firma que usa una de ellas se puede anular con una firma que usa la otra. p.ej,

import java.util.List; class WildcardTest<T> { public void foo(List<? extends T> bar) {} } class WildcardTest2 extends WildcardTest<Object> { @Override public void foo(List<?> bar) {super.foo(bar);} }


De un punto práctico a la mayoría de la gente, <? extends Object> <? extends Object> es el mismo que <?> , como todos han sugerido aquí.

Sin embargo, difieren en dos puntos muy pequeños y sutiles:

  1. El JVMS (Especificación de máquina virtual Java) tiene una especificación especial para los comodines ilimitados, ya que ClassFileFormat-Java5 especifica que el comodín ilimitado se codifica como * , mientras que codifica un comodín delimitado por el objeto como +Ljava/lang/Object; . Tal cambio se filtraría a través de cualquier biblioteca que analice el código de bytes. Los escritores de compiladores también tendrían que lidiar con este problema. De las revisiones a "El formato de archivo de la clase"

  2. Desde el punto de vista de la fiabilidad, son diferentes. JLS 4.6 y 4.7 codifican la List<?> Como un tipo confiable, pero la List<? extends Object> List<? extends Object> como un tipo borrado. Cualquier escritor de la biblioteca que agregue .isReifiable() (por ejemplo, mjc lib ) debe tenerlo en cuenta para cumplir con la terminología JLS. Desde JLS 4.6 y 4.7 .


Es complicado...

Para cualquier tipo de variable T , la especificación dice http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4

Cada tipo de variable ... tiene un límite. Si no se declara ningún límite para una variable de tipo, se asume el objeto.

Uno podría pensar que también es cierto para el comodín, y ? ¿Debería ser una taquigrafía para ? extends Object ? extends Object .

Sin embargo, al buscar en la especificación, no hay evidencia de que un comodín deba tener un límite superior (o un límite inferior). El "sin límites" ? Se trata de manera consistente y distinta de los comodines acotados.

Podríamos deducir de las reglas de subtipos, esa List<?> Y List<? extends Object> List<? extends Object> son subtipos entre sí, es decir, son básicamente del mismo tipo.

Pero la especificación los trata por separado sin embargo. Por ejemplo, http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7 List<?> Es un tipo confiable, pero la List<? extends Object> List<? extends Object> no es, lo que significa

// ok List<?>[] xx = {}; // fail List<? extends Object>[] yy = {}; // ok boolean b1 = (y instanceof List<?>); // fail boolean b2 = (y instanceof List<? extends Object>);

Aunque no entiendo por qué. Parece perfectamente correcto decir que un comodín debe tener un límite superior y un límite inferior, predeterminado para Object y null type .


Todo en java, con la excepción de los primitivos, extiende el objeto, por lo que no, no habría diferencia. Autoboxing permite el uso de primitivos, por lo que se podría decir que todo en java es un objeto.


<? extends Object> <? extends Object> es EXACTAMENTE lo mismo que <?> . Lo siento, no tengo una referencia a la mano, pero ... lo es. :)

EDIT: por supuesto, solo estaba pensando desde una perspectiva particular cuando dije eso. Ignorar mi respuesta (que fue bajada correctamente) y ver las respuestas mejor calificadas para la historia real.