2016-05-03 62 views
3

有沒有辦法在Java中獲取字段的泛型類型?使用relection獲取字段的泛型類型

我有以下對象變量:

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

現在我嘗試使用反射來獲得誰擁有ScheduleView類型與WantedClass作爲泛型類型的所有對象變量:

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 */ 
}); 

的事情是我如果泛型類型爲WantedClass,還希望檢查if語句。我使用的方法也試過getGenericType()但似乎這樣的事情是不可能的:

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

那麼,有沒有辦法讓通用字段的類型?

+0

號這些是在編譯時擦除。您無法檢索該類型。 – f1sh

+2

@ f1sh你確定嗎?這些不是類型變量(我假設)。 –

+2

@ f1sh如果所有的泛型類型都在編譯時被擦除,爲什麼'System.out.println(field.getGenericType());'print' control.ScheduleView '? –

回答

4

您必須檢查該字段是否爲ParameterizedType,然後檢查getActualTypeArguments的內容,例如,

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

使用流@Andy特納回答的實現:

// 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的使用現在已經被誇大了。 – srborlongan

+0

@Holger過濾器函數的冗長度下降。 – srborlongan