Pierwszy punkt: możesz usunąć niezaznaczone ostrzeżenie o operacji, zastępując argument Class c
wartością Class<T> c
. To może być wszystko, czego potrzebujesz ... w takim przypadku ... = :-)
Drugi punkt: Zwykle kod wywołujący SomeContainer.subset() będzie znał podczas kompilacji typ U (z kontekstu logicznego) . To musi być sprawa dla ciebie, w przeciwnym razie nie będzie w stanie przekazać Class c
argument w
Spróbuj:.
class SomeContainer<T> extends ArrayList<T>{
public <U extends T> SomeContainer subset(Class<U> c){
SomeContainer<U> output = new SomeContainer<U>();
// put filtered elements into output
return output;
}
}
Zobacz co zrobiłem tam?
Wprowadzono drugi parametr w wywołaniu metody: U extends T
. Użyto tego również w argumencie z Class<U> c
.
Rozmówca będzie powoływać się jak (gdzie X jest wybrany podklasę T):
SomeContainer<X> mySubset = mySomeContainer.subset(X.class); // type inference
SomeContainer<X> mySubset = mySomeContainer.<X>subset(X.class); // type arg specified
Jeśli potrzebujesz czegoś bardziej dynamiczny niż ten, symbole wieloznaczne mogą pomóc - pozwalającą na „rodziny” parametised typy być przekazywane w & out:
public SomeContainer<? extends X> subset(Class<? extends X> c){
jest to „plastikowy” interfejs funkcji: można powrócić SomeContainer<T>
lub SomeContainer<X>
dla każdego X, które jest podklasy T. następuje również działa:
public SomeContainer<? super Z> subset(Class<? extends X> c){
Jednakże w innym Poster powiedział generyczni konstrukt czasie kompilacji, są wymienione podczas kompilacji z wygenerowanego kodu nierodzajowego. Oznacza to, że nie można dynamicznie decydować o typie używanym do utworzenia typu ogólnego za pomocą pojedynczej linii kodu.Ale możesz oszukać trochę: Jeśli masz ograniczoną liczbę podklas T, powiedzmy X, Y i Z, gdzie Z rozszerza Y, a Y rozszerza Z, wtedy możesz użyć staroświeckiego, hacky "jeśli instrukcja". Spróbuj:
klasa SomeContainer rozciąga ArrayList {
public SomeContainer<? extends X> subset(Class<? extends X> c){
SomeContainer<? extends X> output = null;
// would like to use: "if (c instance of Class<Z>)"
// but instanceof does not allow generic type arguments
if (c.getName().equals(Z.class.getName())) {
SomeContainer<Z> outputZ = new SomeContainer<Z>();
// put filtered elements into outputZ
output = outputZ;
} else if (c.getName().equals(Y.class.getName())) {
SomeContainer<Y> outputY = new SomeContainer<Y>();
// put filtered elements into outputZ
output = outputY;
} else if (c.getName().equals(X.class.getName())) {
SomeContainer<X> outputX = new SomeContainer<X>();
// put filtered elements into outputZ
output = outputX;
}
return output;
}
}
proste! (lub nie) = :-)
Ostrzeżenie dotyczy tego, że używasz 'Class' zamiast' Class > '. I nie jestem pewien, czy możesz używać typów dynamicznych w parametrach szablonu. – vainolo
* Zatem zawiera tylko elementy określonego podtypu U * Dlaczego nie zadeklarować z tym konkretnym podtypem U? – m0skit0