Java często może wnioskować generics na podstawie argumentów (a nawet typu zwracanego, w przeciwieństwie do np. C#).Wnioskowane generatory wieloznaczne w typie zwrotnym
Sprawa w punkcie: Mam rodzajowe klasy Pair<T1, T2>
który przechowuje tylko parę wartości i mogą być używane w następujący sposób:
Pair<String, String> pair = Pair.of("Hello", "World");
Sposób of
wygląda tak:
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
Bardzo ładne. Jednak to nie działa już w następnym użytkowej sprawy, która wymaga symboli wieloznacznych: (. Zwróć uwagę na wyraźny obsady aby List.class
poprawny typ)
Pair<Class<?>, String> pair = Pair.of((Class<?>) List.class, "hello");
kod nie powiedzie się z powodu następującego błędu (pod warunkiem przez Eclipse):
niezgodność typów: nie można przekonwertować z
TestClass.Pair<Class<capture#1-of ?>,String>
doTestClass.Pair<Class<?>,String>
Jednak jawne wywołanie konstruktora nadal działa zgodnie z oczekiwaniami:
Pair<Class<?>, String> pair =
new Pair<Class<?>, String>((Class<?>) List.class, "hello");
Może ktoś wyjaśnić to zachowanie? Czy to projekt? Czy jest to wymagane? Czy robię coś złego, czy natknąłem się na wadę projektu/błędu w kompilatorze?
Dzikie przypuszczenie: the „capture # 1-of?” Jakoś wydaje się sugerować, że wieloznaczny jest wypełniana przez kompilator w locie, dzięki czemu Wpisz Class<List>
, a tym samym braku konwersji (od Pair<Class<?>, String>
do Pair<Class<List>, String>
) . Czy to jest poprawne? Czy istnieje sposób obejścia tego?
pod względem kompletności, albowiem o to uproszczona wersja klasy Pair
:
public final class Pair<T1, T2> {
public final T1 first;
public final T2 second;
public Pair(T1 first, T2 second) {
this.first = first;
this.second = second;
}
public static <T1, T2> Pair<T1, T2> of(T1 first, T2 second) {
return new Pair<T1, T2>(first, second);
}
}
Wygląda na to, że konwerter widzi podpis "of", ponieważ zwraca parę rozszerza klasę,? rozszerza klasę > typ. Dla klas końcowych wydaje się dość sprytny, aby zredukować część wydłużoną, dlatego nie narzeka na Ciąg. –
Zed
Hmmm, interesujące. Dzięki za linkowanie mnie tutaj. – jjnguy
Teraz działa w java8. Docelowy typ jest również konsultowany w celu wnioskowania. – ZhongYu