2010-11-24

Reflecting generic type parameters in Java

If you one is introspecting an object class in Java, it was always a problem to be able to find out, what is the actual type of the generic type parameter for a class field or property.

Ok, yesterday Daniel and I ware listening to a presentation about EclipseLink from a guy from Oracle (or a company, that is working with Oracle, but this is not so important). The question about Generic Type erasure was in our minds all the time, when the guy showed how EclipseLink is generating adapter classes for his model classes. Ok, we asked about the issue, and he showed us how one can extract generic type parameter information for object fields using reflection methods. This approach will work only on the Field classes actually, but this is more then enough to be able to extract actual generic parameter types for class fields :)

Here is a simple example, that I made inspired by this information:

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable;
import java.util.Arrays;
import java.util.Map;

import org.junit.Before;
import org.junit.Test;

public class GenericTypeParameterDemo {

 static final class MyGenericType<e extends Number> {
  public Map<String, E> map;
 }
 
 @Before
 public void setUp() throws Exception {
 }
 
 @Test
 public void extractGenericParameters() throws Exception {
  Field field = MyGenericType.class.getDeclaredField("map");

  Type fieldGenericType = field.getGenericType();
  ParameterizedType parametrizedFieldType = (ParameterizedType) fieldGenericType;

  for (Type actualParameterType : parametrizedFieldType.getActualTypeArguments()) {
   if ( actualParameterType instanceof TypeVariable<?>) {
    Type[] bounds = TypeVariable.class.cast(actualParameterType).getBounds();
    System.out.println(actualParameterType.toString() + 
     " with bounds " + Arrays.toString(bounds) );
   } else {
    System.out.println(actualParameterType);
   }
  }
 }
}

It is really simple, as you can see on lines 25 and 26. The trick is to really check if the result of Field.getGenericType()
is actually an instance of ParameterizedType. One can look up also other children of Type interface, that can bring more details on the structure of your field types.

4 comments:

Mohamed said...

http://www.scribd.com/doc/163398138/Java-Reflection-with-Generics-Practical-Case

Valentine Gogichashvili said...

Mohamed, why do you think somebody should be interested in non-free presentation about something as trivial as reflections in Java?

Richard S. Maddox said...

Great information very nice post.thank you for sharing
crack software

HAPP Chibuzor said...

poor time management skills is a primary reason why students aren’t ready for “real world challenges” on the job and why so many hire the service in a panic. Writing is a “threshold skill” for hiring and promoting professional employees,http://www.huffingtonpost.com/donna-marie-williams/college-students-use-essa_b_8773028.html
so if your goal is to get your dream job and climb the corporate ladder in your chosen field, use your college years to strengthen your writing and time management skills