2013-09-27 14 views
5

Dlaczego tak się dzieje. Jeśli przekażę anonimową klasę ogólną do metody określania typu - wszystko jest w porządku. Ale jeśli mogę przekazać przedmiot w tej metodzie - wyjście konsola jest E.Typowe określenie typu działania

public static void main(String[] args) { 

    printType(new ArrayList<Integer>() {}); 
    printType(new ArrayList<Integer>()); 

} 

public static void printType(final List<?> list) { 
    System.out.println(((ParameterizedType) list.getClass().getGenericSuperclass()).getActualTypeArguments()[0]); 
} 

konsoli:

class java.lang.Integer 

E 

Proszę mi wyjaśnić.

+0

co próbujesz zrobić? –

+0

cóż, drukujesz typeparameter z listy –

+0

Próbuję uzyskać parametr typu w środowisku wykonawczym –

Odpowiedz

7

Pierwsze wywołanie przechodzi instancję anonimowej podklasy ArrayList<Integer>. Tak, to jest podobny do:

class YourClass extends ArrayList<Integer> 

i wywołanie metody jak:

printType(new YourClass()); 

generycznego nadklasą YourClass lub anonimową klasę w Twoim przypadku jest tylko ArrayList<Integer>. Tak, to wyjście jest jasne.


Jeśli chodzi o drugi przypadek, użytkownik przekazuje instancję o numerze ArrayList<Integer>. I definicja tej klasy wygląda następująco:

public class ArrayList<E> extends AbstractList<E> 
     implements List<E>, RandomAccess, Cloneable, java.io.Serializable 

Więc, rodzajowy nadklasą tutaj jest AbstractList<E>.

konkretyzacji typu generic zakładowego samym Class przykład:

Zauważ, że wszystkie instancji z ArrayList dzielić tę samą klasę w czasie wykonywania:

new ArrayList<Integer>().getClass() == new ArrayList<String>().getClass(); 

Powyższe porównanie daje true. Ponieważ zarówno getClass() wywołanie daje powrotem do Ciebie:

class java.util.ArrayList 

Zobacz JLS 8.1.2: Generic Classes and Type Parameters:

Ogólny deklaracja klasy definiuje zestaw typów parametrycznych (§4.5), po jednym dla każdej możliwej wezwaniem typu parametr sekcja według argumentów typu. Wszystkie te sparametryzowane typy mają tę samą klasę w czasie wykonywania.

Na przykład, wykonując kod:

Vector<String> x = new Vector<String>(); 
    Vector<Integer> y = new Vector<Integer>(); 
    boolean b = x.getClass() == y.getClass(); 

spowoduje zmiennej b posiadających wartość true.

Innymi słowy, getGenericSuperClass() metoda nie daje rzeczywisty typ argumentu używanego podczas tworzenia instancji swoją klasę, ale parametr typu stosowanego w klasie jest rozciągającej. Teraz, ponieważ ogólna nadklasa java.util.ArrayList jest AbstractList<E>. I dlatego parametr typu otrzymasz tylko E.

Powiązane problemy