Mam następujący problem podczas korzystania z java generic. Zasadniczo muszę wykonać konwersję z listy podtypu na listę jego nadtypu i definiuję taką metodę:

public static <T> List<T> getList(List<? extends T> input) {
    ArrayList<T> list = new ArrayList<T>();
    list.addAll(input);
    return list;
}

Jednak nie jestem pewien, jak mogę wywołać tę metodę? Biorąc pod uwagę typ A, B rozszerza A:

List<A> alist = getList(List<B> blist);

Ma typ niezgodności, ponieważ w tym przypadku dostarczam tylko informacje o typie B do wywołania metody.

Jak mogę wywołać metodę z dostarczonymi informacjami o typie A?

Dzięki.

2
Wudong 27 lipiec 2011, 06:42

2 odpowiedzi

Najlepsza odpowiedź
List<B> blist = ...
List<A> alist = ClassName.<A>getList(blist);

Zauważ, że możesz również użyć tutaj konstruktora ArrayList:

List<A> alist = new ArrayList<A>(blist);
5
ColinD 27 lipiec 2011, 06:48
Nie wiedziałem, że możesz zrobić ClassName.<A>getList(blist) w java
 – 
Eng.Fouad
27 lipiec 2011, 06:59
Czy nie powinno to być ClassName.getList(blist)? Określasz oba typy ogólne? Wydaje mi się, że potrzebuję tego przynajmniej na moim kompilatorze Java 6 ...
 – 
Greg Mattes
27 lipiec 2011, 07:03
1
Myślę, że droga „po prostu zadzwoń do konstruktora” jest drogą do zrobienia.
 – 
Greg Mattes
27 lipiec 2011, 07:03
1
@Greg: Nie, metoda ma tylko jeden parametr typu ogólnego, T, i jako taki może akceptować tylko jeden argument typu, A w tym przypadku. A ma znaczenie, ponieważ jest to żądany typ zwrotu. B nie ma większego znaczenia poza tym, że musi to być podtyp A.
 – 
ColinD
27 lipiec 2011, 07:19
@ColinD: ach, tak, masz rację. Bawiłem się jakimś kodem na to pytanie i w pewnym momencie miałem metodę, która miała dwa parametry typu, ale oba nie muszą być nazwane, jeden może być wieloznacznym, mój zły, dzięki (nadal myślę, że po prostu wywołanie konstruktora jest prawdopodobnie najlepszym rozwiązaniem ;)
 – 
Greg Mattes
27 lipiec 2011, 17:26

Co powiesz na

public static void <T, S extends T> List<T> getList(List<S> input)
0
Jim Garrison 27 lipiec 2011, 06:57
1
To niestety nie dodaje niczego do wersji List<? extends T>. Wywołania nadal nie są kompilowane bez określenia argumentów typu.
 – 
ColinD
27 lipiec 2011, 07:22
Zgadza się: nie ma sensu dodawać S, jeśli jest używane tylko raz
 – 
newacct
27 lipiec 2011, 15:11