How can I determine the type of a generic field in Java?
Have a look at Obtaining Field Types from the Java Tutorial Trail: The Reflection API.
Basically, what you need to do is to get all java.lang.reflect.Field
of your class and call (check edit below). To get all object fields including public, protected, package and private access fields, simply use Field#getType()
on each of themClass.getDeclaredFields()
. Something like this:
for (Field field : Person.class.getDeclaredFields()) {
System.out.format("Type: %s%n", field.getType());
System.out.format("GenericType: %s%n", field.getGenericType());
}
EDIT: As pointed out by wowest in a comment, you actually need to call Field#getGenericType()
, check if the returned Type
is a ParameterizedType
and then grab the parameters accordingly. Use ParameterizedType#getRawType()
and ParameterizedType#getActualTypeArgument()
to get the raw type and an array of the types argument of a ParameterizedType
respectively. The following code demonstrates this:
for (Field field : Person.class.getDeclaredFields()) {
System.out.print("Field: " + field.getName() + " - ");
Type type = field.getGenericType();
if (type instanceof ParameterizedType) {
ParameterizedType pType = (ParameterizedType)type;
System.out.print("Raw type: " + pType.getRawType() + " - ");
System.out.println("Type args: " + pType.getActualTypeArguments()[0]);
} else {
System.out.println("Type: " + field.getType());
}
}
And would output:
Field: name - Type: class java.lang.String
Field: children - Raw type: interface java.util.List - Type args: class foo.Person
Here's an example that answers my question
class Person {
public final String name;
public final List<Person> children;
}
//in main
Field[] fields = Person.class.getDeclaredFields();
for (Field field : fields) {
Type type = field.getGenericType();
System.out.println("field name: " + field.getName());
if (type instanceof ParameterizedType) {
ParameterizedType ptype = (ParameterizedType) type;
ptype.getRawType();
System.out.println("-raw type:" + ptype.getRawType());
System.out.println("-type arg: " + ptype.getActualTypeArguments()[0]);
} else {
System.out.println("-field type: " + field.getType());
}
}
This outputs
field name: name -field type: class java.lang.String field name: children -raw type:interface java.util.List -type arg: class com.blah.Person