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> 的话,也可以继续取。

猜你喜欢

转载自blog.csdn.net/hustzw07/article/details/89281662
今日推荐