Czytam poprzez następnym rozdziale w samouczku Java: http://docs.oracle.com/javase/tutorial/java/generics/capture.htmlJava Generics Wildcard vs użytkowania Wpisywane Generics
Zaczyna się od stwierdzenia, że poniższy kod generuje błąd ze względu na fakt, że przechwytywanie nie mogą być zamieniane na Object więc metoda set
nie może potwierdzić, że obiekt jest typu capture # 1:
import java.util.List;
public class WildcardError {
void foo(List<?> i) {
i.set(0, i.get(0));
}
}
I nieco zrozumieć uzasadnienie tego. i.get zwraca obiekt, a kompilator nie może ustalić, czy obiekt jest typu przechwytywania nr 1, więc nie może dopasować go do drugiego argumentu w sposób bezpieczny dla określonych typów.
Następnie zaleca stosowanie poniższy kod, aby to metoda pracy:
public class WildcardFixed {
void foo(List<?> i) {
fooHelper(i);
}
// Helper method created so that the wildcard can be captured
// through type inference.
private <T> void fooHelper(List<T> l) {
l.set(0, l.get(0));
}
}
I nieco zrozumieć dlaczego ten kod działa, jak również, w tym kodzie, l.get
jest gwarancją typu T, tak może on być przekazany jako argument typu T.
Co ja nie rozumiem, dlaczego nie można po prostu użyć metody takie jak to, bez pomocnika:
class GenericsTest {
static <K> void bar(List<K> l) {
l.set(0, l.get(l.size() - 1));
}
public static void main(String[] args) {
List<Integer> lst = Arrays.asList(1, 2, 3, 4);
bar(lst);
System.out.println(lst); // [4, 3, 2, 4]
}
}
tj. Jeśli zamierzasz używać wnioskowania o typie, dlaczego nie używać po prostu generycznych wyrażeń pisanych nad wieloznacznikiem i funkcją pomocnika? Czy w tym scenariuszu jest jakaś korzyść z używania symboli wieloznacznych? W jakich przypadkach wolisz używać wieloznacznika zamiast typowego?
Co oznacza "static void", według ciebie? –
@Mike Dla mnie oznacza to, że K jest parametrem typu, który ma zastosowanie tylko do zakresu metody. Java korzysta z inferencji typów, aby dowiedzieć się, co K ma być w czasie wykonywania. W pokazanym przykładzie przechodzę w instancji listy, więc kompilator wskazuje, że K ma wartość całkowitą. K może być dowolnym typem referencji, a typy odniesienia rozciągają się od Object, więc uważam K, że w tym przypadku jest to po prostu inny sposób pisania >. –
Shashank
@Mike Nie wiem ... wydaje się być taki sam jak zwykła metoda void. Nie wiedziałem, że K miał coś wspólnego z powrotem. Używam tylko następującej składni: http://docs.oracle.com/javase/tutorial/java/generics/methods.html – Shashank