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

type - lower bound java



Lista<? extiende MyType> (5)

Tengo una pregunta de Java sobre los genéricos. Declaré una lista genérica:

List<? extends MyType> listOfMyType;

Luego, en algún método, intento instanciar y agregar elementos a esa lista:

listOfMyType = new ArrayList<MyType>(); listOfMyType.add(myTypeInstance);

Donde myTypeInstance es solo un objeto de tipo MyType ; no compilará Dice:

El método add (captura # 3-of? Extends MyType) en el tipo List <capture # 3-of? extends MyType> no es aplicable para los argumentos (MyType)

¿Alguna idea?


Aquí hay un hilo similar: ¿cómo se pueden agregar elementos a una colección genérica comodín?

Para tener una idea de cómo funcionan los genéricos, consulte este ejemplo:

List<SubFoo> sfoo = new ArrayList<SubFoo>(); List<Foo> foo; List<? extends Foo> tmp; tmp = sfoo; foo = (List<Foo>) tmp;

El problema es que no fue diseñado para variables locales / miembros, sino para firmas de funciones, por eso es tan desagradable.


Considerar:

class MySubType extends MyType { } List<MySubType> subtypeList = new ArrayList<MySubType>(); List<? extends MyType> list = subtypeList; list.add(new MyType()); MySubType sub = subtypeList.get(0);

sub ahora contiene un MyType que está muy mal.


No debería necesitar usar la sintaxis de captura comodín en su caso, simplemente declarando

List<MyType> listOfMytype;

debería ser suficiente. Si desea saber exactamente por qué, el Tutorial de genéricos de Java tiene más de lo que siempre desearía saber acerca de la locura esotérica de Java Generics. La página 20 aborda su caso específico.

En cuanto a por qué agregar con la captura de comodín no funciona, es porque el compilador no puede determinar exactamente qué subclase de MyType será la lista en todos los casos, por lo que el compilador emite un error.



No sé si esto realmente te ayudará, pero esto es algo que tuve que usar al llamar a un método genérico de Spring Framework y querer devolver también una lista genérica:

public <T> List<T> findAll(String tableName,Class<?> table) { String sql = "SELECT * FROM "+ tableName ; List<?> entities = getSimpleJdbcTemplate().query(sql, ParameterizedBeanPropertyRowMapper.newInstance(table)); return (List<T>) entities; }

Parece que la parametrización necesita que uses el? inicie sesión en la lista para recibir los resultados y luego envíe la lista al tipo de devolución esperada.

Todavía estoy deslumbrado por los genéricos ...