2013-09-27 20 views
5

Perché questo sta accadendo. Se passo classe anonima generico per digitare il metodo di determinazione - tutto è buono. Ma se mi passate oggetto in questo metodo - uscita della console è E.Determinazione del tipo generico di runtime

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 

spiegare a me.

+0

cosa stai cercando di fare? –

+0

bene stai stampando il typeparameter del tuo elenco –

+0

Sto provando ad ottenere parametri di tipo in runtime –

risposta

7

La prima chiamata passa un'istanza di una sottoclasse anonima di ArrayList<Integer>. Quindi, è simile a:

class YourClass extends ArrayList<Integer> 

e richiamando il metodo come:

printType(new YourClass()); 

La superclasse generica YourClass o la classe anonima nel tuo caso è solo ArrayList<Integer>. Quindi, quell'uscita è chiara.


quanto riguarda il tuo secondo caso, si passa un'istanza di ArrayList<Integer> stessa. E la definizione di questa classe si presenta come:

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

Così, la superclasse generica qui è AbstractList<E>.

la creazione di istanze di tipo generico quota stessa Class esempio:

Si noti che il tutto l'istanza del ArrayList condividono la stessa classe in fase di esecuzione:

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

Il confronto di cui sopra vi darà true. Poiché sia ​​l'invocazione getClass() restituisce a voi:

class java.util.ArrayList 

Vedi JLS 8.1.2: Generic Classes and Type Parameters:

una dichiarazione di classe generica definisce un insieme di tipi parametrizzati (§4.5), una per ogni possibile invocazione del tipo parametro sezione per argomenti tipo. Tutti questi tipi parametrizzati condividono la stessa classe in fase di esecuzione.

Ad esempio, eseguendo il codice:

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

effettuerà la variabile b tiene il valore true.

In altre parole, getGenericSuperClass() metodo non vi darà l'argomento tipo effettivo di utilizzare mentre istanziare la classe, ma il parametro tipo usato nella classe si sta estendendo. Ora, poiché la superclasse generica di java.util.ArrayList è AbstractList<E>. E quindi il parametro tipo che ottieni sarà solo E.