2013-10-08 16 views
11

Mein Projekt gehören Reflexion und ich bin derzeit Umgang mit generischen Typen. Ich habe es geschafft, den generischen Typ aus einer Liste zu erhalten (java.util.List) mit:Java erhalten generische Art der Sammlung

if(originalField.getGenericType() instanceof ParameterizedType){ 
    ParameterizedType pt = (ParameterizedType) originalField.getGenericType(); 
    Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0]; 
} 

Ich habe auch eine Collection<String> und es stellt sich heraus, dass Sammlung kann NICHT zu ParameterizedType gegossen werden.

Hat jemand eine Idee, wie man die Zeichenfolge (oder welchen Typ auch immer) aus der Sammlung holt?

Ich habe über Java Löschungen gelesen, also bin ich mir dessen bewusst, aber nachdem ich die generischen aus der Liste, dachte ich, dass vielleicht jemand einen anderen "Trick" kennt.

Danke.

EDITED: Ich Iterieren mit allen Feldern der Klasse über:

for (Field originalField : someClass.getDeclaredFields()) 

Und dann, wenn ich etwas List<String> Field, mit dem obigen Code gegenüber ich die String als Subklasse bekommen Variable.

+1

Können Sie etwas mehr Code zeigen. Es ist nicht klar, was hier vor sich geht. Wenn die Methode für "List" funktioniert, gibt es einen Grund, warum es nicht für "Collection" funktioniert. –

+0

Auch wenn Sie den generischen Typ des Feldes erhalten, können Sie nicht viel damit machen. Was ist der Zweck in Ihrem Fall? –

+0

Rohit Jhon - der Code funktioniert für die Liste, aber nicht für die Sammlung. Während der Laufzeit wurde gesagt, dass Collection nicht in ParameterizedType umgewandelt werden kann (wie ich in der Frage erwähnt habe). Sotirious Delimanolis - Der Zweck dieses Codes ist es, Code zu generieren, so dass ich den Typ des generischen – Gumba

Antwort

12

Ihr Ansatz ist in Ordnung. Es sollte sowohl für List<String> als auch für Collection<String> funktionieren. finden Sie in diesem Beispielcode Zum Beispiel:

public class Demo { 

    List<String> list = new ArrayList<>(); 
    Collection<String> coll = new ArrayList<>(); 

    public static void main(String args[]){ 

     Class<Demo> clazz = Demo.class; 
     Field[] fields = clazz.getDeclaredFields(); 

     for (Field field: fields) { 

      Type type = field.getGenericType(); 

      if (type instanceof ParameterizedType) { 

       ParameterizedType pType = (ParameterizedType)type; 
       Type[] arr = pType.getActualTypeArguments(); 

       for (Type tp: arr) { 
        Class<?> clzz = (Class<?>)tp; 
        System.out.println(clzz.getName()); 
       } 
      } 
     } 
    } 
} 

diese ausdruckt:

java.lang.String 
java.lang.String 
1

Soweit ich weiß, löscht Java den Typ vollständig, so dass der kompilierte Code keine Spuren des Werts enthält, den Sie den Parametertypen zugewiesen haben. Alle parametrischen Typen werden in konkrete Typen übersetzt, mit Typ-Castings und ähnlichen Dingen.

In dem Code, den ich bisher gesehen habe, wenn eine Klasse den Wert ihres generischen Typs kennen muss, zwingt sie ein Objekt davon Typ (oder die Klasse), die als Parameter übergeben werden soll. Etwas wie:

class A<T> { 
    private final Class<T> parameterType; 

    public A(Class<T> parCls) { 
     parameterType = parCls; 
    } 

    public A(T tObj) { 
     parameterType = tObj.getClass(); 
    } 
} 
+0

Wie ich in meiner Frage erwähnt habe, bin ich mir der Java-Löschung bewusst, aber ich schaffte es (wie Sie in meinem Code sehen können), das Generische aus dem List-Typ zu bekommen. – Gumba

+0

Das ist der Typparameter, nicht der Wert, den Sie ihm zugewiesen haben. –

0

Sie benötigen die ParameterizedType lösen verwenden unabhängig von der Art wurde definiert auf. Zum Beispiel mit TypeTools:

class Foo<T> { 
    public T bar; 
} 

class StringFoo extends Foo<String> {} 

Type barType = Foo.class.getDeclaredField("bar").getGenericType(); 
Class<?> t = TypeResolver.resolveRawClass(barType, StringFoo.class); 
assert t == String.class; 

Hier ist der Wert von T wurde in StringFoo definiert, so können wir TypeResolver verwenden, um die Roh-Klasse für unser Feld der Art zu lösen mit StringFoo

Verwandte Themen