Reputation: 730
Is there a way to obtain the generic type of a field in Java?
I have following object variables:
protected ScheduleView<WantedClass> scheduleLine1;
protected ScheduleView<SomeOtherClass> scheduleLine2;
Now I try using reflection to obtain all the object variables who have ScheduleView
as type with WantedClass
as generic type:
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 */
});
The thing is I also want to check in the if-Statement if the generic type is WantedClass
. I also tried using the method getGenericType()
but it seems something like this is not possible:
field.getGenericType() == ScheduleView<WantedClass>.class
So is there a way to get the generic type of a field?
Upvotes: 3
Views: 401
Reputation: 4579
An implementation of @Andy Turner's answer using streams:
// 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)
;
Upvotes: 2
Reputation: 140494
You have to check if the field is a ParameterizedType
, and then inspect the contents of getActualTypeArguments
, e.g.
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());
}
}
}
}
Upvotes: 4