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

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

ParameterizedType使用简单了解相关推荐

  1. 超简单-用协程简化你的网络请求吧,兼容你的老项目和旧的网络请求方式

    前言 在Kotlin协程(后简称协程)出来之后,颠覆了我们很多工具类的封装方式,大大简化了我们很多api的调用,并且使异步操作逻辑更清晰了 其中一个很标志性的地方就属网络请求了,以前的网络请求方式声明 ...

  2. 通过java反射实现简单的关于MongoDB的对象关系映射(ORM).

    通过阅读MongoDB  3.2.1的官方文档中关于java 编程发现最新的文档并没有实现对对象到Document的映射,所以自己有了利用反射实现简单的关系映射. 1.定义抽象类:AbstractMo ...

  3. 对JDBC进行简单的封装

      由于最近使用jdbc使用的比较频繁,在使用的过程做了一些简单的封装.   在这里简单的记录一下,方便以后使用.迷路的大神请勿见笑.   数据库使用的Oracle. 使用时用dao层类extends ...

  4. 基于ElasticsearchRepository进行简单封装实现非空更新,saveOrUpdate[笔记]

    基于ElasticsearchRepository进行简单封装 封装用到的2个自定义类 repository层 service层 service实现类 使用时注意 封装用到的2个自定义类 public ...

  5. 如何判断一个bean是不是pojo 或者说简单bean by Introspector 和反射

    妙用spring工具类. 解决 method读取缓存问题, 解决 父类注解获取问题 Spring AnnotationUtils.findAnnotation ClassUtils.isPrimiti ...

  6. MyBatis框架简单实现

    MyBatis框架简单实现 1. MyBatis框架概念 2. MyBatis框架原理分析 3. MyBatis框架实现验证 1. MyBatis框架概念 mybatis三种实现方式 mybatis提 ...

  7. 手写Mybatis源码(原来真的很简单!!!)

    目录 一.JDBC操作数据库_问题分析 二.自定义持久层框架_思路分析 三.自定义框架_编码 1.加载配置文件 2.创建两个配置类对象 3.解析配置文件,填充配置类对象 4.创建SqlSessionF ...

  8. 简单的实现轮播图和RecyclerView效果

    简单的实现的效果,可以吸取里面的知识点. 效果图: 首先写网络权限: <uses-permission android:name="android.permission.INTERNE ...

  9. Android工厂设计模式(简单工厂,工厂方法,抽象工厂,BitmapFactory简单工厂分析,Retrofit抽象工厂分析)

    文章目录 创建型设计模式(简单工厂,工厂方法,抽象工厂) 一.简单工厂模式 引出简单工厂模式 二.工厂方法模式 三.抽象工厂模式 Android源码中用到的工厂模式举例 一.BitmapFactory ...

最新文章

  1. Could not resolve archetype org.apache.maven.archetypes:maven-archetype-quickstart
  2. oracle 回闪技术恢复误删数据
  3. 跨域解决方案之CORS
  4. 2014 ACM/ICPC 鞍山赛区网络赛(清华命题)
  5. 05-WIFI通讯客户端搭建
  6. Hadoop HIVE
  7. 流程DEMO-合同会审表
  8. CCF201912-1 报数
  9. Spring 源码分析(四) ——MVC(六)M 与 C 的实现
  10. python实现简单购物商城_如何用python语言实现简单购物商城
  11. 威海二职工业机器人专业_工业机器人专业主要学什么?
  12. HTML页面跳转的几种方式(重定向)
  13. c语言省略号电脑键盘怎么打,省略号的快捷键怎么打【图解】
  14. 2013年系统架构师考试题详解
  15. 自定义View实现雨点洒落效果
  16. 2022虎年背景全新UI头像框制作微信小程序源码下载支持多种流量主
  17. 可用的PHP在线云加密系统源码
  18. 3.3 费马质数测试
  19. 从Python爬虫到Spark预处理数据的真实需求[四]
  20. 阿里云HaaS100物联网开发板学习笔记(四)轻应用初步--用javascript连接阿里云物联网平台

热门文章

  1. 小程序填坑之路——文本超出部分隐藏(已解决)
  2. 列举游戏提高玩家留存率的10种途径
  3. pc联想电脑下载最快的方法网站
  4. Excel双引号拼接问题
  5. android 文件管理器 apk,华为手机文件管理器(com.huawei.hidisk) - 10.11.11.301 - 应用 - 酷安...
  6. 2022巨量引擎城市峰会:发布重磅白皮书 提升城市繁荣力
  7. 对一个手游修改器锁机APP的分析
  8. Golang Gob编码(gob包的使用)
  9. MIT 线性代数 Linear Algebra 10: 矩阵的四个space
  10. word格式刷双击没用时