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 arrayType
is 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:
- Is the field generic type? – In this case yes
- What is declaring class? –
ArrayBean
- What is its generic type? –
List<SomeBean<String, Integer>>[][]
- What is its raw type? –
List[][]
- What is the component type the array is holding? – List<SomeBean<java.lang.String, java.lang.Integer>>[][]
- What is the type argument? – SomeBean<java.lang.String, java.lang.Integer>
Java Reflection APIs used to retrieve Generic type details
Class.getField()
– Gets the field objectField.getType()
– Gets the type of the fieldField.getGenericType()
– Gets the generic type. If it is not generic, it will simply return the typeGenericArrayType
– An extension of type, if it is a generic array typeParameterizedType
– An extension of type, if it is just a parameterized type. For exampleSomeBean<String, Integer>
GenericArrayType.getGenericComponentType()
– Gets the component typeParameterizedType.getActualTypeArguments() - Gets the type arguments. For example, if type is
SomeBean<String, Integer>
, type arguments areString
andInteger
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.