2008-11-03 9 views
3

est ici une interface:non-concordance de type avec les génériques

public interface Foo<T> extends Comparable<Foo<T>> { 
    ... 
} 

Et il y a des cours de mise en œuvre de 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 tas de Foos (qui peut vraiment être Foos ou Boos) à l'intérieur d'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<?>> 

va de même pour:

Vector<Foo> vector; 
if (...) 
    vector = giveBar(); 
else 
    vector = giveBoo(); 

Est-ce une superclasse que les deux Bar et Boo étendent la seule solution à ce problème?

Répondre

6

Ce que tout ce code se résume à:

Vector<A> vector = new Vector<B>(); 

Dans ce cas, B extends A, mais ce n'est pas permis parce que les types ne correspondent pas. Pour préciser pourquoi cela ne fonctionne pas, imaginez le code suivant:

Vector<Vector<?>> vector = new Vector<Vector<String>>(); 
vector.add(new Vector<Integer>()); 

type de la variable est d'un vecteur de vecteurs de type inconnu; et ce qui lui est assigné 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 n'a pas d'objection à l'affectation sur la première ligne, il vous permettra 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 le type de composant, tandis que Java oublie les types de composants lorsque le code est compilé. Ps - Pourquoi utilisez-vous Vector plutôt que LinkedList ou ArrayList? Est-ce parce qu'il y a des problèmes de threading?

2

Vous pouvez utiliser

Vector<? extends Foo<?>> vector; 
Questions connexes