Java Generics
-
Hallo,
eine vielleicht etwas blöde Frage:
public void putAll(Map<? extends K, ? extends V> m)
Wie ist hier der korrekte Typ, den z.B. m.entrySet() zurückliefert?
Set<Map.Entry<? extends K, ? extends V>> i = m.entrySet();
funktioniert auf jeden Fall nicht:
Type mismatch: cannot convert from Set<Map.Entry<capture#1-of ? extends K,capture#2-of ? extends V>> to Set<Map.Entry<? extends K,? extends V>>
Viele Grüße
Christian
-
das ist capture all, also das ?. die extends syntax kann nur in deklarationen verwendet werden.
-
Hallo,
ja, aber wie kriege ich denn jetzt z.B. das entrySet? Rein technisch ist auf jeden Fall möglich, das hier funktioniert z.B. wunderbar:
for ( Map.Entry<? extends K, ? extends V> curEntry : m.entrySet() )
Viele Grüße
Christian
-
indem du das capture all verwendest ^^
Set<Map.Entry<?,?>> = m.entrySet();
-
Hallo,
ok, verstanden.
Gibt's dann aber irgendeinen tieferen Sinn, warum man extends nicht überall verwenden kann? Rein technisch sollte das mit der Type Erasure doch zur Laufzeit bestimmt werden können, ob der Typ des Constraint (extends xzy) erfüllt oder nicht.
Chris
-
der compiler trifft hier auf eine problem, dass aus java eigentlich klassisch bekannt ist.
SomeType[] array = getSomeSubTypeArray(); SomeSubType[] subArray = (SomeSubType[])array;
der code geht durch den compiler, da er keine annahmen treffen kann, aber zur laufzeit wird dir das ding aller wahrscheinlichkeit nach mit ner exception um die ohren fliegen, da die type erasure der container typen (hier arrays) nicht kompatibel ist. selbst wenn das array tatsächlich lauter objekte vom typ SomeSubType enthält.
bei generics tritt genau dasselbe zu. aber im gegensatz zur "klassischen" methode, stellt der compiler das bereits fest und schmeisst einen entsprechenden fehler.
vielleicht wird das irgendwann mal geändert, aber derzeit bleibt es bei dieser design entscheidung. und ich glaub, die ist gar nicht mal schlecht.
-
Hallo,
also die Type Erasure finde ich schon mies (die dient doch im Großen und Ganzen nur dazu, die Abwärtskompatibilität zu wahren, oder?).
Habe jetzt aber nochmal über meinen Schnipsel nachgedacht und du hast natürlich recht, es ist vollkommen logisch, dass das nicht geht. Trotzdem schade irgendwie, wenn man mit Generics nicht so sauber entwickeln kann wie mit Templates in C++.
Viele Grüße
Christian
-
Hi,
ich habe gerade das gleiche Problem, allerdings funktioniert bei mir der Vorschlag nicht:
public void putAll( Map< ? extends K, ? extends V > entries ) { Set< Map.Entry< ?, ? > > set = entries.entrySet(); }
Ausgabe:
found : java.util.Set<java.util.Map.Entry<capture#435 of ? extends K,capture#621 of ? extends V>>
required: java.util.Set<java.util.Map.Entry<?,?>>
Set< Map.Entry< ?, ? > > set = entries.entrySet();Was ist da bitte falsch?