Java Reflection GenericArrayType Example

0

Type is the common super interface for all types in the Java programming language. There are many flavors of type.
In this article, we will see how to determine if the type is a generic type and if the generic type is an array type, how to determine the component details so yo will come to know about the ParameterizedType and GenericArrayType

Sample Bean

We will first define couple of beans that contain fields of generic array type. Field arrayTypeis a raw type but genericArrayType is a generic type, holding type argument String. Likewise genericMultiArrayType is a two-dimension generic array type and specialMultiArrayType is a specialized generic array type containing multiple type arguments.

ArrayBean:

package com.javarticles.reflection;

import java.util.List;

public class ArrayBean {
    public List[] arrayType;
    public List<String>[] genericArrayType;
    public List<String>[][] genericMultiArrayType;
    public List<SomeBean<String, Integer>>[][] specialMultiArrayType;
}

SomeBean:

package com.javarticles.reflection;

public class SomeBean<P, Q> {

}

If we want to know the type details of field specialMultiArrayType, we expect the following details:

  1. Is the field generic type? – In this case yes
  2. What is declaring class? – ArrayBean
  3. What is its generic type? – List<SomeBean<String, Integer>>[][]
  4. What is its raw type? – List[][]
  5. What is the component type the array is holding? – List<SomeBean<java.lang.String, java.lang.Integer>>[][]
  6. What is the type argument? – SomeBean<java.lang.String, java.lang.Integer>

Java Reflection APIs used to retrieve Generic type details

  1. Class.getField() – Gets the field object
  2. Field.getType() – Gets the type of the field
  3. Field.getGenericType() – Gets the generic type. If it is not generic, it will simply return the type
  4. GenericArrayType – An extension of type, if it is a generic array type
  5. ParameterizedType – An extension of type, if it is just a parameterized type. For example SomeBean<String, Integer>
  6. GenericArrayType.getGenericComponentType() – Gets the component type
  7. ParameterizedType.getActualTypeArguments() - Gets the type arguments. For example, if type is SomeBean<String, Integer>, type arguments are String and Integer

GenericArrayTypeExample:

package com.javarticles.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.GenericArrayType;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;

public class GenericArrayTypeExample {

    public static void main(String[] args) throws NoSuchFieldException,
            SecurityException {
        printFieldType(ArrayBean.class, "arrayType");
        System.out.println("\n");
        printFieldType(ArrayBean.class, "genericArrayType");
        System.out.println("\n");
        printFieldType(ArrayBean.class, "genericMultiArrayType");
        System.out.println("\n");
        printFieldType(ArrayBean.class, "specialMultiArrayType");
    }

    private static void printFieldType(Class<?> clazz, String fieldName)
            throws NoSuchFieldException, SecurityException {
        System.out.println("Type details of field " + fieldName);
        Field field = clazz.getField(fieldName);
        System.out.println("Declared class: " + field.getDeclaringClass());
        Type genericType = field.getGenericType();
        System.out.println("Generic type: " + genericType.getTypeName());
        Type type = field.getType();
        System.out.println("Type: " + type.getTypeName());
        if (isGenericArrayType(genericType)) {
            printGenericFieldType((GenericArrayType) genericType);
        }
        if (isParameterizedType(genericType)) {
            printParameterizedType((ParameterizedType) genericType);
        }
    }

    private static void printGenericFieldType(GenericArrayType genericArrayType) {
        Type componentType = genericArrayType.getGenericComponentType();
        System.out.println("Component type of : "
                + genericArrayType.getTypeName() + " is "
                + componentType.getTypeName());
        if (isGenericArrayType(componentType)) {
            printGenericFieldType((GenericArrayType) componentType);
        }
        if (isParameterizedType(componentType)) {
            printParameterizedType((ParameterizedType) componentType);
        }
    }

    private static boolean isGenericArrayType(Type type) {
        if (GenericArrayType.class.isAssignableFrom(type.getClass())) {
            System.out.println("Is GenericArrayType ? true");
            return true;
        }
        return false;
    }

    private static boolean isParameterizedType(Type type) {
        return ParameterizedType.class.isAssignableFrom(type.getClass());
    }

    private static void printParameterizedType(ParameterizedType parmType) {
        System.out.println("Parameterized type details of " + parmType); 
        System.out.println("Type name " + parmType.getTypeName());
        System.out.println("Raw type: " + parmType.getRawType());
        System.out.println("Actual type arguments: "
                + Arrays.asList(parmType.getActualTypeArguments()));
        for (Type type : parmType.getActualTypeArguments()) {
            if (isParameterizedType(type)) {
                printParameterizedType((ParameterizedType) type);
            }
        }
    }
}

Output:

Type details of field arrayType
Declared class: class com.javarticles.reflection.ArrayBean
Generic type: java.util.List[]
Type: java.util.List[]


Type details of field genericArrayType
Declared class: class com.javarticles.reflection.ArrayBean
Generic type: java.util.List<java.lang.String>[]
Type: java.util.List[]
Is GenericArrayType ? true
Component type of : java.util.List<java.lang.String>[] is java.util.List<java.lang.String>
Parameterized type details of java.util.List<java.lang.String>
Type name java.util.List<java.lang.String>
Raw type: interface java.util.List
Actual type arguments: [class java.lang.String]Type details of field genericMultiArrayType
Declared class: class com.javarticles.reflection.ArrayBean
Generic type: java.util.List<java.lang.String>[][]
Type: java.util.List[][]
Is GenericArrayType ? true
Component type of : java.util.List<java.lang.String>[][] is java.util.List<java.lang.String>[]
Is GenericArrayType ? true
Component type of : java.util.List<java.lang.String>[] is java.util.List<java.lang.String>
Parameterized type details of java.util.List<java.lang.String>
Type name java.util.List<java.lang.String>
Raw type: interface java.util.List
Actual type arguments: [class java.lang.String]Type details of field specialMultiArrayType
Declared class: class com.javarticles.reflection.ArrayBean
Generic type: java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>[][]
Type: java.util.List[][]
Is GenericArrayType ? true
Component type of : java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>[][] is java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>[]
Is GenericArrayType ? true
Component type of : java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>[] is java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>
Parameterized type details of java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>
Type name java.util.List<com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>>
Raw type: interface java.util.List
Actual type arguments: [com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>]
Parameterized type details of com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>
Type name com.javarticles.reflection.SomeBean<java.lang.String, java.lang.Integer>
Raw type: class com.javarticles.reflection.SomeBean
Actual type arguments: [class java.lang.String, class java.lang.Integer]

Download the source code

This was an example about Java reflection GenericArrayType.

You can download the source code here: javaReflectionGenericArrayTypeExample.zip
Share.

Comments are closed.