2012-06-29 9 views
10

Z efektywnej wersji drugiej wersji Java, punkt 28: "Nie używaj symboli wieloznacznych jako typów zwracania, zamiast zapewniać dodatkową elastyczność dla użytkowników, zmusiłoby to używać symboli wieloznacznych w kodzie klienta. "Dlaczego Guava TypeToken <T> .getRawType() zwraca klasę <? super T> zamiast klasy <T>

public final Class<? super T> getRawType() 

Właśnie zostałem zaznajomienie się z symboli wieloznacznych generycznych zrozumieć ostatnią niesprawdzony ostrzeżenie rzucania mam w kawałku kodu piszę i nie rozumiem dlaczego getRawType() zwraca typ wieloznaczny.

class Base<T>{} 
class Child<T> extends Base<T>{} 

public <C> void test (TypeToken<? extends Base<C>> token) { 
    Class<? extends Base<C>> rawType = (Class<? extends Base<C>>) token.getRawType(); 
} 

muszę rzucać token.getRawType(), ponieważ zwraca

Class<? super ? extends Base<C>> 

Odpowiedz

7

Co jeśli masz TypeToken<ArrayList<String>> i chcesz uzyskać Class<ArrayList> (to jest surowego typu). Jeśli wróci on Class<T>, to zwróci Class<ArrayList<String>>, który nie jest wymagany.

+0

Dzięki @newacct, to jest rzecz Nie zrozumiałem, ale ma sens, że ArrayList rozszerza ArrayList. Klasa opisuje to, co powraca, chociaż jeśli chodzi o kod klienta, może równie dobrze zwrócić klasę , ponieważ zawsze będziesz musiał ją przesłać. – MikeB

0

Jeśli rodzajowe typu "żeton" jest klasą Type (czyli jeśli S w

TypeToken<S> 

jest klasą java.lang.reflect.Type), a następnie TypeToken.getRawType() zwróci surowy typ powiązany z S. Będzie to obiekt klasy, rodzic S.

Zobacz kod źródłowy: TypeToken.

W niektórych przypadkach (jak o wiele granic), strategia wdrożona nie zadziała i posiadające typ surowca jest OK: surowy typ będzie Object.class

Patrz na przykład MoreTypes:

public static Class<?> getRawType(Type type) { 
... 
} else if (type instanceof TypeVariable) { 
    // we could use the variable's bounds, but that'll won't work if there are multiple. 
    // having a raw type that's more general than necessary is okay 
    return Object.class; 

} else { 
... 
} 
+0

Przeczytałam źródło, ale nadal nie mogę znaleźć sytuacji, w której zwracany jest rodzic S. Próbowałem 'new TypeToken () {}. GetRawType()' ale to zwraca klasę WildcardType, nie żadnego rodzica – MikeB

+1

Zauważ, że twoje łącze 'TypeToken' wskazuje na wersję gson. Oto wersja Guava: http://code.google.com/p/guava-libraries/source/browse/guava/src/com/google/common/reflect/TypeToken.java –

Powiązane problemy