2014-06-09 21 views
5

Poniższe stwierdzenia:Dlaczego nie można przypisać I <? rozszerza Type> to <Type>?

URLClassLoader ucl = (URLClassLoader) ClassLoader.getSystemClassLoader(); 
Class<URLClassLoader> uclc = ucl.getClass(); 

niepowodzeniem z błędem:

Type mismatch: cannot convert from Class<capture#2-of ? extends URLClassLoader> to Class<URLClassLoader> 

Dlaczego muszę obsadę, tutaj?

Znalazłem kilka postów wyjaśniających, dlaczego nie możesz zrobić odwrotnego kroku (przypisz T do a), ale jest to (rodzaj) oczywiste i zrozumiałe.

UWAGA: koduję to pod zaćmieniem Luny, więc nie wiem, czy to jest Luna Dziwka, czy jest coś, czego naprawdę nie rozumiem w przypadku leków generycznych.

Odpowiedz

6

Covariance vs contravariance vs invariance

  • Class<? extends URLClassLoader> jest niezmienna.

W rezultacie

Class<? extends URLClassLoader> jest nie podtypu z Class<URLClassLoader>


W Java zmiennej może posiadać odniesienie wystąpienie samego typu lub podtypu.

Stąd

Class<URLClassLoader> uclc = ucl.getClass(); 

jest nieprawidłowy.

Z drugiej strony,

Class<? extends URLClassLoader> uclc = ucl.getClass(); 

byłoby ważny.

+1

można eloborate dlaczego '' Class (lub '' Class ) nie jest podtypem '' Class ? Myślę, że to jest. – skiwi

+0

@swiki: Spróbuj myśleć w kategoriach kolekcji. Czy myślisz, że List powinien być przypisany do listy ? Doprowadzi to do problemów z bezpieczeństwem typu i nie jest dozwolone. Odwrotne przypisanie jest jednak dozwolone. –

+0

Przeczytaj to fantastyczne wyjaśnienie: http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ503 –

1

Why can't assign I <? extends Type> to <Type>?

Bo rzeczywiście <? extends Type> jest supertypem z <Type>! Zastosujmy się do specyfikacji.

4.10.2 Subtyping among Class and Interface Types:

Given a generic type declaration C<F1,...,Fn>, the direct supertypes of the parameterized type C<T1,...,Tn> are all of the following:

  • C<S1,...,Sn>, where Si contains Ti.

4.5.1. Type Arguments of Parameterized Types:

A type argument T1 is said to contain another type argument T2, written T2 <= T1, if the set of types denoted by T2 is provably a subset of the set of types denoted by T1 under the reflexive and transitive closure of the following rules:

  • T <= ? extends T

Wiemy zatem, że skoro ? extends URLClassLoader zawiera URLClassLoader, Class<? extends URLClassLoader> jest supertypem z Class<URLClassLoader>.

Ponieważ narrowing reference conversion jest niedozwolone w ramach assignment context, pojawia się błąd kompilacji.

Należy również pamiętać, że oznacza to odwrotne zadanie jest dozwolone: ​​

Class<URLClassLoader> concrete = URLClassLoader.class; 
Class<? extends URLClassLoader> wildcard = concrete; 
Powiązane problemy