ParameterizedType使用简单了解

本文介绍了如何在Java中使用ParameterizedType来处理范型类型。通过示例展示了如何利用ParameterizedType获取参数化类型的具体信息,以解决在模板方法中消除代码冗余的问题。讲解了范型的类型擦出概念,并提供了使用ParameterizedType获取容器内部类型的代码示例。

之前项目中有一段逻辑:接收消息、解析、校验、业务处理。一开始代码显得冗余,然后改成模板方法。发现不同消息体解析成不同的类。

public abstract class Tests {

    public void handler(String message) {
        InfoA infoA = parse(message);
        try {
            process(infoA);
        } catch (Exception e) {
            exceptionHandler(message, e);
        }
    }

    private InfoA parse(String message) {
        // 省略
        return new InfoA();
    }

    abstract void process(InfoA infoA);

    abstract void exceptionHandler(String message, Exception e);
}

此时是个具体类,为了消除类型,改成范型如下:

public abstract class Tests<T> {

    public void handler(String message) {
        T infoA = parse(message);
        try {
            process(infoA);
        } catch (Exception e) {
            exceptionHandler(message, e);
        }
    }

    T parse(String message) {
        // XXX 怎么写?
        return null;
    }

    abstract void process(T infoA);

    abstract void exceptionHandler(String message, Exception e);
}

最开始想用模板方法和范型的目的就是想减少代码冗余,因此使 parse(String message) 解析成相应的类即可。
这时候就需要 ParameterizedType 了,即参数化类型。查看源码解释如下:

/**
 * ParameterizedType表示参数化的类型,例如
 * Collection<String>。
 * 参数化类型是在A第一次需要时创建的
 * 反射方法,在此包中指定。当一个
 * 创建参数化类型p,泛型类型声明
 * 解析了p的实例化,并创建了p的所有类型参数
 * 递归。看到{@link java.lang.reflect.TypeVariable
 * TypeVariable}获取有关type创建过程的详细信息
 * 变量。重复创建参数化类型没有效果。
 * 一个equals()方法,它等于共享
 * 相同的泛型类型声明,并具有相同的类型参数。
 *
 * @since 1.5
 */

也就是说范型进行了类型擦出,即Collection<String> 与 Collection<Integer> 在JVM中属于相同类型。但我们可以通过ParameterizedType 拿到容器里面的类型。
写法如下:

public abstract class Tests<T> {

    public void handler(String message) {
        T infoA = parse(message);
        try {
            process(infoA);
        } catch (Exception e) {
            exceptionHandler(message, e);
        }
    }

    T parse(String message) {
        Class<T> entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];// 注意这里是第0元素
        return JsonUtils.fromJson(message, entityClass);
    }

    abstract void process(T infoA);

    abstract void exceptionHandler(String message, Exception e);
}

可能有人要问为啥是第0元素,因为只范型里面只有一个。如果是 Tests<T, S> 的话,也可以继续取。

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值