I have been trying to determine the type of a field in a class. I've seen all the introspection methods but haven't quite figured out how to do it. This is going to be used to generate xml/json from a java class. I've looked at a number of the questions here but haven't found exactly what I need.
Example:
class Person {
public final String name;
public final List<Person> children;
}
When I marshall this object, I need to know that the chidren
field is a list of objects of type Person
, so I can marshall it properly.
I had tried
for (Field field : Person.class.getDeclaredFields()) {
System.out.format("Type: %s%n", field.getType());
}
But this will only tell me that it's a List
, not a List
of Person
s
Thanks
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