Java Reflection Generic Type from Class getGenericTypeArgument(Class clazz, int index)

Here you can find the source of getGenericTypeArgument(Class clazz, int index)

Description

Reads the generic type of the given class at the given index.

License

Apache License

Parameter

Parameter Description
clazz the class with generic types
index the index of the generic type

Return

the generic type or null

Declaration

public static Class<?> getGenericTypeArgument(Class<?> clazz, int index) 

Method Source Code

//package com.java2s;
// Licensed under the Apache License, Version 2.0 (the "License");

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class Main {
    /**/*  ww  w  .  j  a  v  a  2 s .  c  om*/
     * Reads the generic type of the given class at the given index.
     * 
     * Note: this doesn't work, if class MyClass implements Super MyConcreteType
     *
     * @param clazz the class with generic types
     * @param index the index of the generic type
     * @return the generic type or null
     */
    public static Class<?> getGenericTypeArgument(Class<?> clazz, int index) {
        Type genericSuperclass = clazz.getGenericSuperclass();
        return findGenericTypeArgument(genericSuperclass, index);
    }

    /**
     * Looks for the concreate Class of a generic of given classRequested.
     *
     * This implementation looks first in super classes and then in super interfaces.
     *
     * @param <T> the generic type
     * @param clazz concrete class
     * @param classRequested class or interface implementing it.
     * @return null if not found.
     */
    public static <T> Class<T> getGenericTypeArgument(Class<?> clazz, Class<T> classRequested) // NOSONAR "Methods should not be too complex" trivial
    {
        Type genericSuperclass = clazz.getGenericSuperclass();
        if (genericSuperclass != null) {
            Class<T> ret = getGenericTypeArgumentFromGenericSuperType(genericSuperclass, classRequested);
            if (ret != null) {
                return ret;
            }
        }

        Type[] genericInterfaces = clazz.getGenericInterfaces();
        if (genericInterfaces == null) {
            return null;
        }
        for (Type genericInterface : genericInterfaces) {
            Class<T> ret = getGenericTypeArgumentFromGenericSuperType(genericInterface, classRequested);
            if (ret != null) {
                return ret;
            }
        }
        Class<?> superClazz = clazz.getSuperclass();
        if (superClazz != null) {
            return getGenericTypeArgument(superClazz, classRequested);
        }
        return null;
    }

    /**
     * Find generic type argument.
     *
     * @param genericSuperclass the generic superclass
     * @param index the index
     * @return the class
     */
    public static Class<?> findGenericTypeArgument(Type genericSuperclass, int index) {
        // CHECKSTYLE.OFF SIMULIERTE_POLYMORPHIE Necesssary for technical reasons (low level handling).
        while (genericSuperclass != null
                && !(ParameterizedType.class.isAssignableFrom(genericSuperclass.getClass()))) {
            genericSuperclass = ((Class) genericSuperclass).getGenericSuperclass();
        }
        // CHECKSTYLE.ON
        if (genericSuperclass instanceof ParameterizedType) {
            Type o = ((ParameterizedType) genericSuperclass).getActualTypeArguments()[index];
            if (o instanceof Class) {
                return (Class<?>) o;
            } else if (o instanceof ParameterizedType) {
                return (Class<?>) ((ParameterizedType) o).getRawType();
            }
        }
        return null;
    }

    /**
     * Looks if generic supertype is paramized with given baseRequested.
     *
     * @param <T> the generic type
     * @param genericSuperclass the generic superclass
     * @param baseRequested the base requested
     * @return the generic type argument from generic super type. null if not found.
     */
    //CHECKSTYLE.OFF FinalParameter Precondition cast
    public static <T> Class<T> getGenericTypeArgumentFromGenericSuperType(Type genericSuperclass,
            Class<T> baseRequested) {
        Type loopVar = genericSuperclass;
        while (loopVar != null && !(ParameterizedType.class.isAssignableFrom(loopVar.getClass()))) {
            loopVar = ((Class<?>) loopVar).getGenericSuperclass();
        }
        if (loopVar != null && ParameterizedType.class.isAssignableFrom(loopVar.getClass())) {
            Type[] typeArgs = ((ParameterizedType) loopVar).getActualTypeArguments();
            for (Type typeArg : typeArgs) {
                if (typeArg instanceof ParameterizedType) {
                    typeArg = ((ParameterizedType) typeArg).getRawType();
                }
                if ((typeArg instanceof Class) == false) {
                    continue;
                }
                if (baseRequested.isAssignableFrom((Class<?>) typeArg) == false) {
                    continue;
                }
                return (Class<T>) typeArg;
            }
        }
        return null;
    }
}

Related

  1. getGenericType(Class target)
  2. getGenericType(Class type)
  3. getGenericType(Class type, Class clazz)
  4. getGenericType(Object o, Class declaringClass, int idx)
  5. getGenericType(Type type, Class rawType, int index)
  6. getGenericTypeArgumentFromGenericSuperType(Type genericSuperclass, Class baseRequested)
  7. getGenericTypeArgumentsOfInheritedType(final Object object, final Class inheritedType)
  8. getGenericTypeClass(Class clazz, int index)
  9. getGenericTypeClasses(List> genericTypeClasses, Type... genericTypes)