Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I determine the type of a generic field in Java?

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 Persons

Thanks

like image 474
Juan Mendes Avatar asked Dec 08 '09 17:12

Juan Mendes


People also ask

How do you find the type of generic class?

You can get around the superfluous reference by providing a generic static factory method. Something like public static <T> GenericClass<T> of(Class<T> type) {...} and then call it as such: GenericClass<String> var = GenericClass. of(String. class) .

What is generic data type in Java?

Generics means parameterized types. The idea is to allow type (Integer, String, … etc., and user-defined types) to be a parameter to methods, classes, and interfaces. Using Generics, it is possible to create classes that work with different data types.

What are the different types of generic boxes in Java?

A Generic Version of the Box Class To update the Box class to use generics, you create a generic type declaration by changing the code "public class Box" to "public class Box<T>". This introduces the type variable, T, that can be used anywhere inside the class.

How are generic methods defined in Java?

The syntax for a generic method includes a list of type parameters, inside angle brackets, which appears before the method's return type. For static generic methods, the type parameter section must appear before the method's return type.


1 Answers

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 Field#getType() on each of them (check edit below). To get all object fields including public, protected, package and private access fields, simply use Class.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 
like image 108
Pascal Thivent Avatar answered Oct 14 '22 11:10

Pascal Thivent