Overview

The org.apache.commons.lang3.reflect.TypeUtils class provides some interesting utility methods in particular with regard to generics.

Examples

Determine the Type Arguments of an Implemented Interface

This can be useful for framework like interfaces where the type arguments of the implementation / extension define the concrete use case.

interface MyInterface extends Runnable, Supplier<String> {}

...
Map<TypeVariable<?>, Type> typeArguments = TypeUtils.getTypeArguments(MyInterface.class, Supplier.class);

// get the TypeVariable of Supplier (has exactly one):
TypeVariable<Class<Supplier>> tv = Supplier.class.getTypeParameters()[0];

// The typeArguments map holds the type assignements with respect to the class analyzed hierarchy.
Type type = typeArguments.get(tv);

System.out.println(type);
// output: class java.lang.String

With a two-liner we can get the actual type arguments:

public static List<Type> getTypes(final Type type, final Class<?> toClass) {
    Map<TypeVariable<?>, Type> typeArguments = TypeUtils.getTypeArguments(type, toClass);
    return Stream.of(toClass.getTypeParameters()).map(typeArguments::get).collect(Collectors.toList());
}

Example:

interface MyInterface extends BiFunction<Integer, List<String>, Supplier<String>> {}

List<Type> types = getTypes(MyInterface.class, BiFunction.class);
// [class java.lang.Integer, java.util.List<java.lang.String>, java.util.function.Supplier<java.lang.String>]

// Note: java.util.List<java.lang.String> and  java.util.function.Supplier<java.lang.String> 
// are of type java.lang.reflect.ParameterizedType

References