Slyh: Generischer Vektor in abstrakter Klasse ...

Beitrag lesen

Hallo,

vorweg: Ich bin kein Generics-Experte, sondern habe Generics nur das
eine oder andere Mal in einfachen Fällen angewendet.

Dein Problem läßt sich wohl auf Type-Erasure zurückführen. Eigentlich
macht deine Implementierung keinen so wirklich großen Sinn, wenn du
mich fragst.

class AbstractVectorHolder
{
  protected Vector<?> allData;

public void setData(Vector<?> data)
  {
    allData = data;
  }

//... der Rest, der für's Problem irrelevant ist.
}

Hier sagst du, daß die Klasse einen typisierten Vector mit unspezifiziertem
Typ aufnehmen kann. Blöderweise ist der Typ zur Compile-Zeit nicht
bekannt. Ergo könntest du hier jetzt z.B. keine get-Methode zur
Klasse hinzufügen, die ein Element aus dem Vector zurückliefert, einfach
weil der Typ nicht bekannt ist.

Zur Laufzeit wäre er das natürlich. Aber Generics sind nun mal eben
genau dafür da, daß sie zur Compile-Zeit sicher sind. Durch einen
Cast, wie du ihn unten probierst, umgehst du diese Sicherheit natürlich
wieder. Bei einem Cast verlässt sich der Compiler aber schlichtweg
auf deine Weisheit und fragt nicht weiter nach. Mit einem Cast geht
alles. Das aber nur am Rande.

Mit deiner Klasse hast du die Information über den Typ zur Compile-Zeit
jedenfalls weggeworfen und wirst ihn auch nicht mehr erhalten können.

class OneVectorHolder extends AbstractVectorHolder
{
//  public void addRow(WasAuchImmer obj)
//  {
//    allData.add(obj);
//  }

//hier noch mehr kram, der für's Problem irrelevant ist
}

Wenn du hier jetzt versuchst ein WasAuchImmer-Objekt in den Vector zu
schreiben, geht das im Grunde deshalb nicht, weil der Vector keinen
konkreten Typ hat. Er hat einen unbekannten Typ. Deshalb kannst du auf
diese Weise auch kein einziges(!) Objekt in den Vector ablegen. Denn
damit würdest du mit der Typsicherheit zur Compile-Zeit brechen. Da
der Compiler nicht weiß, welchen Typ der Vector hat, könntest du alles
mögliche reinstecken, wenn es keinen Compile-Fehler geben würde. Und
bei der nächsten Abfrage (von außerhalb des AbstractVectorHolder-
Objekts, s.u.) würde bei falschem Typ (z.B. String) eine ClassCastException
geworfen werden. Aber das wäre genau das Gegenteil von Compile-Zeit-
Sicherheit. :)

Irgendwo (wo spielt keine Rolle für's Problem) wird dann

OneVectorHolder instanz = new OneVectorHolder();
Vector<WasAuchImmer> data = getVectorOfWasAuchImmer();
instanz.setData(data);

gemacht. Klappt einwandfrei.

Das geht. Du kannst auch prima sowas wie data.add(new WasAuchImmer())
aufrufen. In diesem Scope ist nämlich zur Compile-Zeit(!) bekannt, daß
"data" vom Typ Vector<WasAuchImmer> ist. Im Scope von OneVectorHolder
wurde der Type durch ? gelöscht und ist (zur Compile-Zeit) nicht mehr
bekannt.

Ich hab's mit diversen Casts probiert (z.B: allData.add((Object) obj); ), leider bekomme ich das nicht übersetzt.

Das einzige, was funktioniert, ist
((Vector) allData).add(object);
also ein Cast des Vektors.

Ja, weil du damit aus dem Objekt quasi ein Vector<Object>-Objekt machst.
Da kannst du natürlich alles reinstecken, was von Object abgeleitet ist.
(Also alles.) Wenn du allerdings z.B. ein new Object() reinstecken
würdest, würde ein nachfolgender Aufruf wie "allData.get(5)" zu einer
ClassCastException führen, weil in der (typisierten) get-Methoden eben
intern einen Type-Cast auf "WasAuchImmer" macht.

Vector<?> sollte doch eigentlich ein Vektor beliebigier Objekte sein, insofern verstehe ich nicht, wieso
allData.add(obj); oder allData.add((Object) obj); nicht funktionieren.

Nein, ein Vector<Object> wäre ein Vector beliebiger Objekte. Blöderweise
kriegst du dann bei z.B. get() allerdings auch nur einen Object-Typ
zurück, hast also nur auf die Methoden Zugriff, die in Object definiert
sind.

Gibt es eine Variante, bei der nur das obj gecastet wird, nicht der ganze Vector?
Oder gar eine Variante ganz ohne Cast?

Was willst du eigentlich genau erreichen?

Lies dir mal den Generics-Abschnitt aus 'Java ist auch eine Insel' durch.
Da ist das eigentlich recht gut erklärt. (Zumindest um einen groben
Eindruck zu erhalten.)

Würd mich aber tatsächlich interessieren, was du hier vorhattest.
Vielleicht läßt sich ja gemeinsam eine Lösung finden.

Gruß
Slyh