Digitare la mancata corrispondenza con generici
Domanda
Ecco un'interfaccia:
public interface Foo<T> extends Comparable<Foo<T>> {
...
}
E ci sono alcune classi che implementano questa interfaccia:
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() {
...
}
}
Ora voglio mantenere un mucchio di Foos (che potrebbero essere davvero Foos o Boos) all'interno di un vettore.
Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...)
vector = bar.giveBar();
else
vector = boo.giveBoo();
Ottengo:
Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>
Lo stesso vale per:
Vector<Foo> vector;
if (...)
vector = giveBar();
else
vector = giveBoo();
È una superclasse che sia Bar che Boo estendano l'unica soluzione a questo problema?
Soluzione
Ciò a cui si riduce tutto quel codice è:
Vector<A> vector = new Vector<B>();
In questo caso B estende A, ma ciò non è consentito perché i tipi non corrispondono. Per chiarire perché questo non funziona, immagina il seguente codice:
Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());
Il tipo di variabile è di un vettore di vettori di tipo sconosciuto ; e ciò che gli viene assegnato è un vettore di vettori di stringhe . La seconda riga aggiunge un vettore di numeri interi . Il tipo di componente della variabile Vector<?>
, che accetta Vector<Integer>
; ma il tipo di componente del vettore reale è Vector<String>
, che non lo è. Se il compilatore non si opponesse all'assegnazione sulla prima riga, ti consentirebbe di scrivere la seconda riga errata senza essere individuata.
I generici di C # hanno una restrizione simile, ma la differenza è che una classe generica in C # memorizza il suo tipo di componente, mentre Java dimentica i tipi di componente quando viene compilato il codice.
ps - Perché mai stai usando Vector
anziché LinkedList
o ArrayList
? È perché ci sono problemi di threading coinvolti?
Altri suggerimenti
Puoi usare
Vector<? extends Foo<?>> vector;