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?

È stato utile?

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;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top