java 泛型参数具体类型获取、泛型返回具体类型获取

本文探讨了Java泛型在Spring生态和MyBatis框架中的应用,通过反射获取泛型参数的具体类型,实现序列化、反序列化以及类型检查等功能。以解决因类型不匹配导致的问题,如账号ID的Java类型与数据库类型不符引发的故障。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自从java支持泛型后,现在,spring生态中的框架及目前的应用都使用了泛型。有的框架如mybatis和spring都需要反射获取类型,以使得序列化和反序列化得以实现,但有时候我们根据项目的需要获取这些具体类型。

比如,mybatis  orm环境下,数据库字段类型和java类型不匹配检测的功能,需要利用这种方法获取类中方法的具体类型,结合com.mysql.cj.MysqlType枚举中类型的映射关系列出不匹配的实例、表、java类型、数据库列、java属性字段等信息。【为什么要检测呢,因为近期看到由于账号id  java类型为Long,而数据库类型为int,导致故障发生)

 

为了能得到类中方法的泛型参数具体类型或者返回的泛型参数具体类型,我们必须使用反射及类型ParameterizedType。

java类型的鼻祖类是java.lang.reflect.Type,这个类型包括了原生类型、泛型类型、数组类型等等。

/**
 * Type is the common superinterface for all types in the Java
 * programming language. These include raw types, parameterized types,
 * array types, type variables and primitive types.
 *
 * @since 1.5
 */
public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

在反射使用过程中,我们必须根据具体的类型来采取不同的策略,那么就需要关系type类的所有子类型:

其中,第二个子类ParameterizedType就是本文所要使用的。

例如;


import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author sdcuike
 * @DATE 2019/9/30
 */
public class Demo {
    public static void main(String[] args) throws NoSuchMethodException {
        Method method = DemoInterface.class.getDeclaredMethod("demo", List.class);
        //返回类型解析
        Type returnType = method.getGenericReturnType();
//        if (returnType instanceof Class) {
//            System.out.println("返回类型(不是泛型:" + returnType);
//            System.out.println();
//        }
        if (returnType instanceof ParameterizedType) {
            ParameterizedType pType = (ParameterizedType) returnType;
            System.out.print("返回泛型类型:");
            Stream.of(pType.getActualTypeArguments()).forEach(System.out::print);
            System.out.println();
        }

        //参数类型解析
        List<Object> parameters = new ArrayList<>();
        Type[] types = method.getGenericParameterTypes();
        for (Type type : types) {
//            if (type instanceof Class) {
//                parameters.add(type);
//            }
            if (type instanceof ParameterizedType) {
                ParameterizedType pType = (ParameterizedType) type;
                Stream.of(pType.getActualTypeArguments()).forEach(t -> parameters.add("泛型参数" + t));
            }
        }

        System.out.println("参数:" + parameters);
    }

    interface DemoInterface {
        List<String> demo(List<Long> ids);
    }
}

根据具体类型,强制类型转换后就可以获得这些具体的参数了类型。

输出:

返回泛型类型:class java.lang.String
参数:[泛型参数class java.lang.Long]

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dreamer who

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值