How to Elegantly Retrieve Generic Types in Spring with ResolvableType

This article explains how to extract generic type information in Spring, first by manually parsing class hierarchies with reflection and then using Spring 4's ResolvableType utility, providing code examples and API references for fields, methods, constructors, and instances.

Java Architecture Diary
Java Architecture Diary
Java Architecture Diary
How to Elegantly Retrieve Generic Types in Spring with ResolvableType

Introduction

Spring's source code is a treasure trove; many tools can be found there. The author's open-source project mica is built entirely on Spring for basic enhancements without reinventing the wheel. This article shows how to obtain generic types gracefully in Spring.

Getting Generic Types

Manual parsing

The previous approach, derived from vjtools, uses reflection to read the generic parameter declared on a superclass.

/**
 * 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
 * 注意泛型必须定义在父类处. 这是唯一可以通过反射从泛型获得Class实例的地方.
 * 如无法找到, 返回Object.class.
 * 如public UserDao extends HibernateDao<User,Long>
 * @param clazz clazz The class to introspect
 * @param index the Index of the generic declaration, start from 0.
 * @return the index generic declaration, or Object.class if cannot be determined
 */
public static Class getClassGenericType(final Class clazz, final int index) {
    Type genType = clazz.getGenericSuperclass();
    if (!(genType instanceof ParameterizedType)) {
        logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");
        return Object.class;
    }
    Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
    if ((index >= params.length) || (index < 0)) {
        logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length);
        return Object.class;
    }
    if (!(params[index] instanceof Class)) {
        logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");
        return Object.class;
    }
    return (Class) params[index];
}

ResolvableType utility

Since Spring 4.0, the ResolvableType class simplifies generic type retrieval. The official example demonstrates its usage:

private HashMap<Integer, List<String>> myMap;
public void example() {
    ResolvableType t = ResolvableType.forField(getClass().getDeclaredField("myMap"));
    t.getSuperType(); // AbstractMap<Integer, List<String>>
    t.asMap(); // Map<Integer, List<String>>
    t.getGeneric(0).resolve(); // Integer
    t.getGeneric(1).resolve(); // List
    t.getGeneric(1); // List<String>
    t.resolveGeneric(1, 0); // String
}

Detailed usage

Obtain generic information from a Field

ResolvableType.forField(Field)

Obtain generic information from a Method parameter

ResolvableType.forMethodParameter(Method, int)

Obtain generic information from a Method return type

ResolvableType.forMethodReturnType(Method)

Obtain generic information from a Constructor parameter

ResolvableType.forConstructorParameter(Constructor, int)

Obtain generic information from a Class

ResolvableType.forClass(Class)

Obtain generic information from a Type

ResolvableType.forType(Type)

Obtain generic information from an instance

ResolvableType.forInstance(Object)

For more API details, see the ResolvableType Javadoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/ResolvableType.html

References

[1]

mica: https://gitee.com/596392912/mica [2] Spring ResolvableType Javadoc: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/core/ResolvableType.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaReflectionspringGenericsResolvableType
Java Architecture Diary
Written by

Java Architecture Diary

Committed to sharing original, high‑quality technical articles; no fluff or promotional content.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.