useful type parameter method generic example are java generics

type - java generics parameter



Genéricos de Java: Lista<Container<?>>=new LinkedList<Container<Double>>() está prohibido? (3)

Editar: Estaba buscando en la sección de preguntas frecuentes de Angelika Langer una explicación, pero no encontré ninguna (probablemente esté allí, pero escondida en alguna parte de las 500 páginas).

Muchas gracias por la respuesta. Encontré una explicación en las Preguntas frecuentes, y después de algunos entrecerrar los ojos, creo que lo entiendo.

http://www.angelikalanger.com/GenericsFAQ/FAQSections/TypeArguments.html#What%20do%20multilevel%20wildcards%20mean ?

¿Cómo es que en Java puedo escribir

List<?> list = new LinkedList<Double>();

pero no

List<Container<?>> list = new LinkedList<Container<Double>>();

donde Container es algo así como

public class Container<T> { ... }

Esto surgió porque tengo un método que acepta una List<Container<?>> , y me gustaría usar Arrays.asList para pasarle argumentos:

process(Arrays.asList(new Container<Double>(), new Container<Double>()));

Pero el lenguaje no lo permite porque infiere el tipo de Arrays.asList para ser List<Container<Double>> y no se puede asignar a List<Container<?>> .

Si agrego un Contenedor con parámetros de cadena a la llamada,

process(Arrays.asList(new Container<Double>(), new Container<String>()));

todavía no funciona, porque infiere el tipo List<Container<? extends Serializable & Comparable<?>>> List<Container<? extends Serializable & Comparable<?>>> para Arrays.asList. Solo si paso algo que no es Comparable ni Serializable, funciona correctamente.

Por supuesto, puedo poner un yeso y hacer que el compilador se calle, pero me pregunto si estoy haciendo algo mal aquí.


Cada parametrización debe ser wildcarded:

List<? extends Container<?>> list = new LinkedList<Container<Double>>();

Editar: Estaba buscando en la sección de preguntas frecuentes de Angelika Langer una explicación, pero no encontré ninguna (probablemente esté allí, pero escondida en alguna parte de las 500 páginas).

La forma de pensar sobre esto es que cada parametrización es independiente, y el compilador no deducirá información sobre la parametrización a menos que explícitamente lo indique.


Considera lo que pasaría si pudieras.

List<Container<Double>> list1 = new LinkedList<Container<Double>>(); List<Container<?>> list2 = list1; // this shouldn''t be allowed, because of the below Container<String> foo = new Container<String>(); foo.add("hi"); list2.add(foo); // legal, because Container<String> is a subtype of Container<?> Container<Double> bar = list1.get(0); Double x = bar.get(0); // type error; it is actually a String object // this indicates that type safety was violated

Sin embargo, usando List<? extends Container<?>> List<? extends Container<?>> no tiene este problema porque no se puede poner nada (excepto null ) en una lista de este tipo (porque no hay ningún tipo que garantice que sea un subtipo de " ? extends Container<?> ") .