objeto - Genéricos en Java, usando comodines
metodos genericos java (2)
Esta situación exacta se trata en el Tutorial de genéricos de Java .
Tenga en cuenta que [con el comodín], aún podemos leer elementos de [la
Collection
genérica] y darles el tipoObject
. Esto siempre es seguro, ya que sea cual sea el tipo real de la colección, sí contiene objetos. Sin embargo, no es seguro agregarle objetos arbitrarios:
Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
Como no sabemos cuál es el tipo de elemento de
c
, no podemos agregarle objetos. El métodoadd()
toma argumentos de tipoE
, el tipo de elemento de la colección. Cuando el parámetro de tipo real es?
, representa un tipo desconocido. Cualquier parámetro que pasemos paraadd
debería ser un subtipo de este tipo desconocido. Como no sabemos qué tipo es, no podemos pasar nada. La única excepción esnull
, que es miembro de todo tipo.
(énfasis mío)
Tengo una pregunta sobre Genéricos en Java, es decir, el uso de comodines. Tengo un ejemplo de clase GenClass como este:
public class GenClass<E> {
private E var;
public void setVar(E x) {
var = x;
}
public E getVar() {
return var;
}
}
Tengo otra clase simple:
public class ExampleClass {
}
He escrito la siguiente clase de prueba:
public class TestGenClass {
public static void main(String[] str) {
ExampleClass ec = new ExampleClass();
GenClass<ExampleClass> c = new GenClass<ExampleClass>();
c.setVar(ec);
System.out.println(c.getVar()); // OUTPUT: ExampleClass@addbf1
}
}
Ahora, si uso un comodín y escribo en la clase de prueba esto:
GenClass<?> c = new GenClass<ExampleClass>();
en el lugar de:
GenClass<ExampleClass> c = new GenClass<ExampleClass>();
el compilador no tiene ningún problema con esta nueva declaración, sin embargo, se queja de
c.setVar(ec);
Dice que "el método (setVar ()) no es aplicable para los argumentos (ExampleClass)". ¿Por qué recibo este mensaje?
Pensé que la forma en que usé el comodín hace que la variable de referencia c sea del tipo GenClass, que aceptaría como parámetro cualquier clase; en el lugar de EI tendría cualquier clase. Esta es solo la declaración de la variable. Luego lo inicializo con
new GenClass<ExampleClass>()
lo que significa que creo un objeto de tipo GenClass, que tiene como parámetro una clase de tipo ExampleClass. Entonces, creo que ahora E en GenClass será ExampleClass, y podría usar el método setVar (), dándole como argumento algo de tipo ExampleClass. Esta fue mi suposición y comprensión, pero parece que a Java no le gusta, y no tengo razón. Cualquier comentario es apreciado, gracias.
mmyers tiene la respuesta correcta, pero solo quería comentar esta parte de tu pregunta (que parece ser la razón por la que quieres usar el comodín):
Pensé que la forma en que usé el comodín hace que la variable de referencia c sea del tipo GenClass, que aceptaría como parámetro cualquier clase; en el lugar de EI tendría cualquier clase. Esta es solo la declaración de la variable. Luego lo inicializo con
Si realmente quieres lograr esto, podrías hacer algo así como sin errores de compilación:
GenClass<Object> gc = new GenClass<Object>();
gc.setVar(new ExampleClass());
Pero, una vez más, si quieres declarar una instancia de GenClass
que puede contener cualquier tipo, no estoy seguro de por qué querrías usar genéricos: podrías usar la clase raw:
GenClass raw = new GenClass();
raw.setVar(new ExampleClass());
raw.setVar("this runs ok");