2011-11-04 15 views
5

Esistono altre domande correlate, ad es. 6624113, 3403909, 4516891 ma la mia domanda è più semplice e specifica.Utilizzo di getActualTypeArguments in un contesto generico

Voglio sapere in fase di esecuzione che tipo la mia classe è stata parametrizzata con - Voglio un oggetto Classe del tipo del parametro type. A causa della cancellazione dei caratteri, l'espressione T.class non funziona e non esiste alcuna funzione come typeof(T) in C# per ottenerlo.

Tuttavia, c'è un "uber-reflection" disponibile tramite ParameterizedType e classi correlate, che mi fa quasi tutto il tragitto.

import java.lang.reflect.ParameterizedType; 

public class MyClass<T> { 
    public static void main(String[] args) { 
     new MyClass<Integer>().printTypeParam(); 
    } 

    public void printTypeParam() { 
     class DummyT extends MyClass<T> {} 
     class DummyString extends MyClass<String> {} 

     ParameterizedType ptT = 
      ((ParameterizedType) DummyT.class.getGenericSuperclass()); 

     ParameterizedType ptString = 
      ((ParameterizedType) DummyString.class.getGenericSuperclass()); 

     System.out.println("DummyT: " + ptT + " " + ptT.getActualTypeArguments()[0]); 
     System.out.println("DummyString: " + ptString + " " + ptString.getActualTypeArguments()[0]); 

    } 
} 

Quando eseguo quanto sopra vedo questa uscita:

DummyT: MyClass<T> T 
DummyString: MyClass<java.lang.String> class java.lang.String 

Come si può vedere, questo funziona per quando gli argomenti di tipo sono noti al momento della compilazione alla riga di codice che contiene la chiamata a getGenericSuperClass, ma se quella chiamata si occupa di generici, stampa semplicemente il nome del parametro type.

C'è un modo per ottenere la prima riga da stampare java.lang.Integer anziché T?

risposta

3

Non è possibile, semplice e semplice. Integer non è reificato, è completamente erased. Se non mi credi, compila il file una volta con Integer e una volta con Long. I due file di classe binari saranno assolutamente identici.

La cancellazione di tipo è una dura realtà che non sarà possibile aggirare. Suggerisco di ripensare al motivo per cui è necessario invece di seguire il percorso di introduzione degli hack per provare a evitare it.

utili AngelikaLanger Generics frequenti argomenti:

+1

in realtà ho fatto quello che avete suggerito, e si sarà sorpreso di sentire lei ha ragione: 2 file sono creati: MyClass $ 1DummyString.class MyClass $ 1DummyT.class MyClass.class e sono binari-identici se cambio il tipo sulla riga 5 a Long invece o f intero. –

+0

Sto usando con piacere la soluzione/pattern di passare un'istanza di classe al costruttore - ero solo curioso di sapere se la soluzione meno dettagliata fosse possibile. –

Problemi correlati