2016-05-03 12 views
3

erhalten Gibt es eine Möglichkeit, den generischen Typ eines Felds in Java zu erhalten?Generischen Typ eines Felds mit der Auswahl

ich folgende Objektvariablen haben:

protected ScheduleView<WantedClass> scheduleLine1; 
protected ScheduleView<SomeOtherClass> scheduleLine2; 

Jetzt habe ich Reflektion Versuchen Sie es mit der alle Objektvariablen zu erhalten, die mit WantedClass als generische Typ ScheduleView als Typ haben:

Arrays.asList(this.getClass().getDeclaredFields()).stream().map(field -> { 
    ScheduleView<WantedClass> retValue = null; 

    System.out.println(field.getGenericType()); // prints control.ScheduleView<dto.WantedClass> 

    try { 
     if (field.getType() == ScheduleView.class) { // here I also want to check if the generic type is WantedClass 
      retValue = (ScheduleView<WantedClass>) field.get(this); 
     } else { 
      retValue = null; 
     } 
    } catch (IllegalAccessException e) { 
     retValue = null; 
    } finally { 
     return retValue; 
    } 
}).filter(scheduleView -> scheduleView != null).forEach(scheduleView -> { 
     /* some more code */ 
}); 

Das, was ich ist Außerdem möchten Sie die if-Anweisung einchecken, wenn der generische Typ WantedClass lautet. Ich habe auch versucht, das Verfahren unter Verwendung von getGenericType(), aber es scheint so etwas wie dies nicht möglich ist:

field.getGenericType() == ScheduleView<WantedClass>.class 

So gibt es eine Möglichkeit, den generischen Typen ein Feld zu bekommen?

+0

No. Die auf Compile-Zeit gelöscht werden. Sie können diesen Typ nicht abrufen. – f1sh

+2

@ f1sh bist du sicher? Dies sind keine Typvariablen (ich nehme an). –

+2

@ f1sh Wenn alle generischen Typen zur Kompilierzeit gelöscht werden, warum wird 'System.out.println (field.getGenericType());' print 'control.ScheduleView '? –

Antwort

4

Sie müssen überprüfen, ob das Feld eine ParameterizedType ist, und dann den Inhalt von , z.

for (Field field : Ideone.class.getDeclaredFields()) { 
     Type type = field.getGenericType(); 
     if (type instanceof ParameterizedType) { 
      ParameterizedType ptype = (ParameterizedType) type; 
      if (ptype.getRawType() == ScheduledView.class) { 
       if (ptype.getActualTypeArguments().length == 1 
        && ptype.getActualTypeArguments()[0] == WantedClass.class) { 
        // Do whatever with the field. 
        System.out.println(field.getName()); 
       } 
      } 
     } 
    } 

Ideone demo

2

Eine Implementierung Antwort @Andy Turners Streams mit:

// For each declared field in the class... 
Arrays.stream(Ideone.class.getDeclaredFields()) 
    // select fields... 
    .filter(
    // that have a generic type... 
    field -> Stream.of(field.getGenericType()) 
     // that is an instance of ParametrizedType... 
     .filter(ParameterizedType.class::isInstance) 
     .map(ParameterizedType.class::cast) 
     // whose raw type is ScheduledView... 
     .filter(ptype -> ptype.getRawType().equals(ScheduledView.class)) 
     // and whose actual type arguments... 
     .map(ParameterizedType::getActualTypeArguments) 
     .flatMap(Arrays::stream) 
     // include WantedClass... 
     .anyMatch(WantedClass.class::equals) 
) 
    // then get their names... 
    .map(Field::getName) 
    // and print them. 
    .forEach(System.out::println) 
; 
+0

@Holger Stream Verwendung wurde jetzt übertrieben. – srborlongan

+0

@Holger Filterfunktion hat ihre Ausführlichkeit verringert. – srborlongan

Verwandte Themen