2013-09-27 3 views
5

Warum das passiert. Wenn ich die anonyme generische Klasse an die Typbestimmungsmethode weitergebe, ist alles in Ordnung. Aber wenn ich Objekt in dieser Methode übergeben - Konsolenausgabe ist E.Runtime generische Typbestimmung

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]); 
} 

Console:

class java.lang.Integer 

E 

Bitte erklären Sie mir.

+0

Was versuchen Sie zu tun? –

+0

Nun drucken Sie den Typparameter Ihrer Liste –

+0

Ich versuche, Parameter des Typs in Runtime zu bekommen –

Antwort

7

Der erste Aufruf übergibt eine Instanz einer anonymen Unterklasse von ArrayList<Integer>. Also, es ist ähnlich wie:

class YourClass extends ArrayList<Integer> 

und die Methode aufgerufen wird, wie:

printType(new YourClass()); 

Die generische Super von YourClass oder die anonymen Klasse in Ihrem Fall ist ArrayList<Integer> nur. Also, diese Ausgabe ist klar.


Was Ihren zweiten Fall sind vorbei Sie eine Instanz von ArrayList<Integer> selbst. Und Definition dieser Klasse wie folgt aussieht:

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

So, hier die generische Super AbstractList<E> ist.

Instanziierung der generischen Typ Anteil gleiche Class Beispiel:

Beachten Sie, dass die ganze Instanziierung ArrayList zur Laufzeit die gleiche Klasse teilen:

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

Der Vergleich wird Ihnen true geben. Da sowohl der getClass() Aufruf gibt zurück zu Ihnen:

class java.util.ArrayList 

Siehe JLS 8.1.2: Generic Classes and Type Parameters:

Eine generischen Klassendeklaration definiert eine Reihe von parametrisierte Typen (§4.5), ein für jeden möglichen Aufruf des Typs Parameterbereich nach Typ Argumente. Alle diese parametrisierten Typen teilen sich die gleiche Klasse zur Laufzeit.

beispielsweise die Ausführung der Code:

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

in der Variablen b führen wird, den Wert hält true.

Mit anderen Worten, wird getGenericSuperClass() Methode, die Sie nicht das Argument tatsächliche Typ geben Sie verwenden, während die Klasse instanziiert wird, aber der Typ-Parameter in der Klasse verwendet wird, erstreckt. Nun, da die generische Oberklasse von java.util.ArrayListAbstractList<E> ist. Und daher ist der Typ-Parameter, den Sie erhalten, nur E.