Non concordance des types avec les génériques
Question
Voici une interface:
public interface Foo<T> extends Comparable<Foo<T>> {
...
}
Et certaines classes implémentent cette interface:
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() {
...
}
}
Maintenant, je veux garder un groupe de Foos (qui peuvent vraiment être des Foos ou des Boos) dans un vecteur.
Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...)
vector = bar.giveBar();
else
vector = boo.giveBoo();
je reçois:
Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>
Même chose pour:
Vector<Foo> vector;
if (...)
vector = giveBar();
else
vector = giveBoo();
Est-ce qu'une super-classe dont Bar et Boo offrent la solution unique à ce problème?
La solution
Tout ce code se résume à:
Vector<A> vector = new Vector<B>();
Dans ce cas, B étend A, mais ce n'est pas autorisé car les types ne correspondent pas. Pour expliquer pourquoi cela ne fonctionne pas, imaginez le code suivant:
Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());
Le type de la variable est un vecteur de vecteurs de type inconnu ; et ce qui lui est attribué est un vecteur de vecteurs de chaînes . La deuxième ligne ajoute un vecteur d’entiers à cela. Le type de composant de la variable Vector<?>
, qui accepte Vector<Integer>
; mais le type de composant du vecteur réel est Vector<String>
, ce qui n'est pas le cas. Si le compilateur ne s'est pas opposé à l'affectation sur la première ligne, cela vous permettrait d'écrire la deuxième ligne incorrecte sans être repéré.
Les génériques de C # ont une restriction similaire, mais la différence est qu’une classe générique en C # stocke son type de composant, tandis que Java oublie les types de composant lors de la compilation du code.
ps - Pourquoi utilisez-vous Vector
plutôt que LinkedList
ou ArrayList
? Est-ce parce qu'il y a des problèmes de threads?
Autres conseils
Vous pouvez utiliser
Vector<? extends Foo<?>> vector;