Typenkonflikt mit Generika
Frage
Hier ist eine Schnittstelle:
public interface Foo<T> extends Comparable<Foo<T>> {
...
}
Und es gibt einige Klassen die diese Schnittstelle implementieren:
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() {
...
}
}
Jetzt möchte ich eine Reihe von Foos halten (das wirklich Foos oder Boos sein kann) innerhalb eines Vektors.
Bar bar = new Bar();
Boo boo = new Boo();
Vector<Foo<?>> vector;
if (...)
vector = bar.giveBar();
else
vector = boo.giveBoo();
ich:
Type mismatch: cannot convert from Vector<Foo<SomethingElse>> to Vector<Foo<?>>
Das gleiche gilt für:
Vector<Foo> vector;
if (...)
vector = giveBar();
else
vector = giveBoo();
Ist eine übergeordnete Klasse, die sowohl Bar und Boo die einzige Lösung für dieses Problem verlängern?
Lösung
Was das alles Code läuft darauf hinaus, ist:
Vector<A> vector = new Vector<B>();
In diesem Fall erstreckt sich B A, aber das ist nicht erlaubt, weil die Typen nicht übereinstimmen. Um deutlich zu machen, warum dies nicht funktioniert, stellen Sie sich den folgenden Code:
Vector<Vector<?>> vector = new Vector<Vector<String>>();
vector.add(new Vector<Integer>());
Die Typ der Variable ist ein Vektor von Vektoren unbekannter Art ; und was ihm zugewiesen ist wird, ist ein Vektor von Vektoren von Strings . Die zweite Zeile fügt einen Vektor von ganzen Zahlen zu dem. Der Komponententyp der Variablen Vector<?>
, die Vector<Integer>
annimmt; aber die Komponenten tatsächlichen Vektor wird Vector<String>
, was nicht der Fall. Wenn der Compiler auf die Zuordnung in der ersten Zeile das Objekt nicht, es Ihnen erlauben würde, die falsche zweite Zeile zu schreiben, ohne entdeckt zu werden.
C # 's Generika hat eine ähnliche Einschränkung, aber der Unterschied ist, dass eine generische Klasse in C # speichern sie Komponententyp, während Java-Komponententypen vergisst, wenn der Code kompiliert wird.
ps - Warum in aller Welt verwenden Sie Vector
statt LinkedList
oder ArrayList
? Ist es, weil es ist Threadingprobleme beteiligt?
Andere Tipps
Sie können mit
Vector<? extends Foo<?>> vector;