No coinciden los tipos con los genéricos
Pregunta
Aquí hay una interfaz:
public interface Foo<T> extends Comparable<Foo<T>> {
...
}
Y hay algunas clases que implementan esta interfaz:
public class Bar extends Something implements Foo<Something> {
public Vector<Foo<Bar>> giveBar() {
...
}
}
public class Boo extends SomethingElse implements Foo<SomethingElse> {
public Vector<Foo<Boo>> giveBoo() {
...
}
}
Ahora quiero mantener un montón de Foos (que realmente pueden ser Foos o Boos) dentro de un vector.
Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...)
vector = bar.giveBar();
else
vector = boo.giveBoo();
Obtengo:
Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>
Lo mismo ocurre con:
Vector<Foo> vector;
if (...)
vector = giveBar();
else
vector = giveBoo();
¿Es una superclase en la que tanto Bar como Boo extienden la única solución a este problema?
Solución
Todo lo que se reduce a ese código es:
Vector<A> vector = new Vector<B>();
En este caso, B extiende a A, pero eso no está permitido porque los tipos no coinciden. Para aclarar por qué esto no funciona, imagine el siguiente código:
Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());
El tipo de la variable es de un vector de vectores de tipo desconocido ; y lo que se le asigna es un vector de vectores de cadenas . La segunda línea agrega un vector de enteros a eso. El tipo de componente de la variable Vector<?>
, que acepta Vector<Integer>
; pero el tipo de componente del vector real es Vector<String>
, que no lo hace. Si el compilador no se opuso a la asignación en la primera línea, le permitiría escribir la segunda línea incorrecta sin ser detectado.
Los genéricos de C # tienen una restricción similar, pero la diferencia es que una clase genérica en C # almacena el tipo de componente, mientras que Java olvida los tipos de componentes cuando se compila el código.
ps - ¿Por qué estás usando Vector
en lugar de LinkedList
o ArrayList
? ¿Es porque hay problemas de subprocesos involucrados?
Otros consejos
Puedes usar
Vector<? extends Foo<?>> vector;