2016-05-03 17 views
3

Javaでフィールドの汎用タイプを取得する方法はありますか?Relectionを使用してフィールドのジェネリック型を取得する

私は、オブジェクト変数を次のようしている。

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

今私は、ジェネリック型とWantedClassとタイプとしてScheduleViewを持つすべてのオブジェクト変数を取得するためにリフレクションを使用してみてください:

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-Statementをチェックインします。私はまた、この方法を使用してみました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ストリームの使用量が誇張されました。 – srborlongan

+0

@Holgerフィルタ機能の冗長性が低下しました。 – srborlongan

関連する問題