public static Class[] findParameterTypes(Class type, Method m)
    {
        Type[] genTypes = m.getGenericParameterTypes();
        Class[] types = new Class[genTypes.length];;
        boolean noGenericParameter = true;
        for (int i=0; i < genTypes.length; i++)
        {
            if (Class.class.isInstance(genTypes[i]))
            {
                types[i] = (Class) genTypes[i];
                continue;
            }
            noGenericParameter = false;
            break;
        }
        if (noGenericParameter)
        {
            return types;
        }

        if (type == null || !isJdk15())
        {
            return getParameterTypes(m);
        }

        final Type typeGenericSuperclass = type.getGenericSuperclass();
        if (typeGenericSuperclass == null
            || !ParameterizedType.class.isInstance(typeGenericSuperclass)
            || m.getDeclaringClass().getTypeParameters() == null)
        {
            return getParameterTypes(m);
        }

        if ((types = (Class[]) _genericMethodParameterTypesCache.get(m)) != null)
        {
            ParameterizedType genericSuperclass = (ParameterizedType) typeGenericSuperclass;
            if (Arrays.equals(types, genericSuperclass.getActualTypeArguments())) {
                return types;
            }
        }

        ParameterizedType param = (ParameterizedType)typeGenericSuperclass;
        TypeVariable[] declaredTypes = m.getDeclaringClass().getTypeParameters();

        types = new Class[genTypes.length];

        for (int i=0; i < genTypes.length; i++)
        {
            TypeVariable paramType = null;

            if (TypeVariable.class.isInstance(genTypes[i]))
            {
                paramType = (TypeVariable)genTypes[i];
            } else if (GenericArrayType.class.isInstance(genTypes[i]))
            {
                paramType = (TypeVariable) ((GenericArrayType)genTypes[i]).getGenericComponentType();
            }
            else if (ParameterizedType.class.isInstance(genTypes[i]))
            {
                 types[i] = (Class) ((ParameterizedType) genTypes[i]).getRawType();
                 continue;
            } else if (Class.class.isInstance(genTypes[i]))
            {
                types[i] = (Class) genTypes[i];
                continue;
            }

            Class resolved = resolveType(param, paramType, declaredTypes);

            if (resolved != null)
            {
                if (GenericArrayType.class.isInstance(genTypes[i]))
                {
                    resolved = Array.newInstance(resolved, 0).getClass();
                }

                types[i] = resolved;
                continue;
            }

            types[i] = m.getParameterTypes()[i];
        }

        synchronized (_genericMethodParameterTypesCache)
        {
            _genericMethodParameterTypesCache.put(m, types);
        }

        return types;
    }
public static Class [ ] findParameterTypes ( Class type , Method m ) { Type [ ] genTypes = m . getGenericParameterTypes ( ) ; Class [ ] types = new Class [ genTypes . length ] ; ; boolean noGenericParameter = true ; for ( int i = 0 ; i < genTypes . length ; i ++ ) { if ( Class . class . isInstance ( genTypes [ i ] ) ) { types [ i ] = ( Class ) genTypes [ i ] ; continue ; } noGenericParameter = false ; break ; } if ( noGenericParameter ) { return types ; } if ( type == null || ! isJdk15 ( ) ) { return getParameterTypes ( m ) ; } final Type typeGenericSuperclass = type . getGenericSuperclass ( ) ; if ( typeGenericSuperclass == null || ! ParameterizedType . class . isInstance ( typeGenericSuperclass ) || m . getDeclaringClass ( ) . getTypeParameters ( ) == null ) { return getParameterTypes ( m ) ; } if ( ( types = ( Class [ ] ) _genericMethodParameterTypesCache . get ( m ) ) != null ) { ParameterizedType genericSuperclass = ( ParameterizedType ) typeGenericSuperclass ; if ( Arrays . equals ( types , genericSuperclass . getActualTypeArguments ( ) ) ) { return types ; } } ParameterizedType param = ( ParameterizedType ) typeGenericSuperclass ; TypeVariable [ ] declaredTypes = m . getDeclaringClass ( ) . getTypeParameters ( ) ; types = new Class [ genTypes . length ] ; for ( int i = 0 ; i < genTypes . length ; i ++ ) { TypeVariable paramType = null ; if ( TypeVariable . class . isInstance ( genTypes [ i ] ) ) { paramType = ( TypeVariable ) genTypes [ i ] ; } else if ( GenericArrayType . class . isInstance ( genTypes [ i ] ) ) { paramType = ( TypeVariable ) ( ( GenericArrayType ) genTypes [ i ] ) . getGenericComponentType ( ) ; } else if ( ParameterizedType . class . isInstance ( genTypes [ i ] ) ) { types [ i ] = ( Class ) ( ( ParameterizedType ) genTypes [ i ] ) . getRawType ( ) ; continue ; } else if ( Class . class . isInstance ( genTypes [ i ] ) ) { types [ i ] = ( Class ) genTypes [ i ] ; continue ; } Class resolved = resolveType ( param , paramType , declaredTypes ) ; if ( resolved != null ) { if ( GenericArrayType . class . isInstance ( genTypes [ i ] ) ) { resolved = Array . newInstance ( resolved , 0 ) . getClass ( ) ; } types [ i ] = resolved ; continue ; } types [ i ] = m . getParameterTypes ( ) [ i ] ; } synchronized ( _genericMethodParameterTypesCache ) { _genericMethodParameterTypesCache . put ( m , types ) ; } return types ; }
Finds the appropriate parameter types for the given {@link Method} and
{@link Class} instance of the type the method is associated with.  Correctly
finds generic types if running in >= 1.5 jre as well.

@param type The class type the method is being executed against.
@param m The method to find types for.
@return Array of parameter types for the given method.