Java 泛型之 Type 体系

本贴最后更新于 2705 天前,其中的信息可能已经水流花落

Type 是 java 类型信息体系中的顶级接口,其中 Class 就是 Type 的一个直接实现类。此外,Type 还有有四个直接子接口:ParameterizedType,TypeVariable,WildcardType,GenericArrayType。

这几个接口的介绍如下:

  • Type

它是所有类型的公共接口。包括原始类型、参数化类型、数组类型、类型变量和基本类型。ParameterizedType, TypeVariable, WildcardType,GenericArrayType 这四个接口都是它的子接口。

  • GenericDeclaration

这个接口 Class、Method、Constructor 都有实现,我们就是要用这个接口的 getTypeParameters 方法,它返回一个 TypeVariable[]数组,这个数组里面就是我们定义的类型变量 T 和 K,顺序与我们声明时一样。如果用循环语句将数组打印出来,你会发现只会输出 T 和 K,这可不是我们想要的结果,那么想要获得预期的结果怎么办呢?请继续往下看。

  • TypeVariable

它表示类型变量。比如 T,比如 K extends Comparable<? super T> & Serializable,这个接口里面有个 getBounds()方法,它用来获得类型变量上限的 Type 数组,如果没有定义上限,则默认设定上限为 Object,请注意 TypeVariable 是接口,实际得到的是 TypeVariableImpl 实现类,下面几个接口都一样。

拿 T 和 K 来说明,T 没有定义任何上限,所以它就有一个默认上限 java.lang.Object,实际跟踪代码的时候你会发现 T 的 bounds 属性为空,只有在调用了 getBounds()方法后,才会有一个 Type[1]数组[class java.lang.Object]。而对于 K 来说,调用了 getBounds 方法后,得到的数组是[java.lang.Comparable<? super T>, interface java.io.Serializable],它们的类型却是不一样的,第 1 个是 ParameterizedType,而第二个是 Class.

  • ParameterizedType

ParameterizedType 表示参数化类型,就是上面说的 java.lang.Comparable<? super T>,再比如 List,List,这些都叫参数化类型。得到 Comparable<? super T> 之后,再调用 getRawType()与 getActualTypeArguments()两个方法,就可以得到声明此参数化类型的类(java.lang.Comparable)和实际的类型参数数组([? super T]),而这个? super T 又是一个 WildcardType 类型。

  • WildcardType

它用来描述通配符表达式,上面返回的? super T 正好是这个类型。然后调用 getUpperBounds()上限和 getLowerBounds()下限这两个方法,获得类型变量?的限定类型(上下限),对于本例的通配符(?),它的上限为 java.lang.Object,下限为 T

通过上面几个接口的分析,可以将 Person 类的泛型参数都解析出来,那么 Person 的超类以及实现的接口该怎么处理呢?Class 类里面同样在 1.5 版本加入了 getGenericSuperclass()与 getGenericInterfaces()两个方法,用于返回带参数化类型的超类与接口。

GenericArrayType 其实就是泛型数组类型。

我们说 Class 在一定程度上挽救了擦除的类型信息,我们就可以通过这几个接口来获取被擦除的类型参数信息,这几个接口无非就是对类型参数的一个分类,通过它们提供的一些方法,我们可以逐步的获取到最原始的类型参数的 Class 对象。

具体的说明和 API 大家可以去看文档,我这里记录一个实际的应用,当然在各种框架中的应用比比皆是。

在 JavaEE 的 Dao 层我们一般都会封装出一个通用的泛型 BaseDao,它可以实现对各种实体例如 User,Order 的基本 CRUD,然后具体的 UserDao,OrderDao 等等会去继承它,提供其他的 Dao 方法:

public class UserDao extends BaseDao<User>{}

我们使用的 BaseDao 是基于 DBUtils 的,它需要实体的 Class 对象才能进行通用的查询方法,例如 User 的 Class 对象,我们可以通过构造函数,函数参数等手段传递给 BaseDao,但是有了反射,可以有更优雅的实现。

public class BaseDao<T> { private Class<T> clszz; public BaseDao(){ Type type = this.getClass().getGenericSuperclass();//拿到带类型参数的泛型父类 if(type instanceof ParameterizedType){//这个Type对象根据泛型声明,就有可能是4中接口之一,如果它是BaseDao<User>这种形式 ParameterizedType parameterizedType = (ParameterizedType) type; Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();//获取泛型的类型参数数组 if(actualTypeArguments != null && actualTypeArguments.length == 1){ if(actualTypeArguments[0] instanceof Class){//类型参数也有可能不是Class类型 this.clszz = (Class<T>) actualTypeArguments[0]; }else{ //例如: BaseDao<BaseDao<User>>,获取到的就不是Class,而又是ParameterizedType,即嵌套的 ParameterizedType,一层一层剥开,最终是可以得到User的Class对象的 } } } } public T get(String sql,Object...params){ QueryRunner qr = new QueryRunner(); T obj; Connection connection; try { connection = JdbcUtil.getConnection(); obj = qr.query(connection,sql,new BeanHandler<T>(clszz),params); } catch (SQLException e) { e.printStackTrace(); return null; } return obj; } }
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3201 引用 • 8217 回帖 • 2 关注
  • class
    4 引用 • 3 回帖 • 1 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Sublime

    Sublime Text 是一款可以用来写代码、写文章的文本编辑器。支持代码高亮、自动完成,还支持通过插件进行扩展。

    10 引用 • 5 回帖 • 1 关注
  • 爬虫

    网络爬虫(Spider、Crawler),是一种按照一定的规则,自动地抓取万维网信息的程序。

    106 引用 • 275 回帖
  • Flume

    Flume 是一套分布式的、可靠的,可用于有效地收集、聚合和搬运大量日志数据的服务架构。

    9 引用 • 6 回帖 • 662 关注
  • PWL

    组织简介

    用爱发电 (Programming With Love) 是一个以开源精神为核心的民间开源爱好者技术组织,“用爱发电”象征开源与贡献精神,加入组织,代表你将遵守组织的“个人开源爱好者”的各项条款。申请加入:用爱发电组织邀请帖
    用爱发电组织官网:https://programmingwithlove.stackoverflow.wiki/

    用爱发电组织的核心驱动力:

    • 遵守开源守则,体现开源&贡献精神:以分享为目的,拒绝非法牟利。
    • 自我保护:使用适当的 License 保护自己的原创作品。
    • 尊重他人:不以各种理由、各种漏洞进行未经允许的抄袭、散播、洩露;以礼相待,尊重所有对社区做出贡献的开发者;通过他人的分享习得知识,要留下足迹,表示感谢。
    • 热爱编程、热爱学习:加入组织,热爱编程是首当其要的。我们欢迎热爱讨论、分享、提问的朋友,也同样欢迎默默成就的朋友。
    • 倾听:正确并恳切对待、处理问题与建议,及时修复开源项目的 Bug ,及时与反馈者沟通。不抬杠、不无视、不辱骂。
    • 平视:不诋毁、轻视、嘲讽其他开发者,主动提出建议、施以帮助,以和谐为本。只要他人肯努力,你也可能会被昔日小看的人所超越,所以请保持谦虚。
    • 乐观且活跃:你的努力决定了你的高度。不要放弃,多年后回头俯瞰,才会发现自己已经成就往日所仰望的水平。积极地将项目开源,帮助他人学习、改进,自己也会获得相应的提升、成就与成就感。
    1 引用 • 487 回帖 • 2 关注
  • AWS
    11 引用 • 28 回帖 • 8 关注
  • 架构

    我们平时所说的“架构”主要是指软件架构,这是有关软件整体结构与组件的抽象描述,用于指导软件系统各个方面的设计。另外还有“业务架构”、“网络架构”、“硬件架构”等细分领域。

    142 引用 • 442 回帖 • 1 关注
  • 知乎

    知乎是网络问答社区,连接各行各业的用户。用户分享着彼此的知识、经验和见解,为中文互联网源源不断地提供多种多样的信息。

    10 引用 • 66 回帖
  • 支付宝

    支付宝是全球领先的独立第三方支付平台,致力于为广大用户提供安全快速的电子支付/网上支付/安全支付/手机支付体验,及转账收款/水电煤缴费/信用卡还款/AA 收款等生活服务应用。

    29 引用 • 347 回帖
  • 博客

    记录并分享人生的经历。

    273 引用 • 2389 回帖 • 2 关注
  • OpenStack

    OpenStack 是一个云操作系统,通过数据中心可控制大型的计算、存储、网络等资源池。所有的管理通过前端界面管理员就可以完成,同样也可以通过 Web 接口让最终用户部署资源。

    10 引用 • 1 关注
  • 创业

    你比 99% 的人都优秀么?

    82 引用 • 1395 回帖
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 284 关注
  • 思源笔记

    思源笔记是一款隐私优先的个人知识管理系统,支持完全离线使用,同时也支持端到端加密同步。

    融合块、大纲和双向链接,重构你的思维。

    26098 引用 • 108353 回帖 • 1 关注
  • Office

    Office 现已更名为 Microsoft 365. Microsoft 365 将高级 Office 应用(如 Word、Excel 和 PowerPoint)与 1 TB 的 OneDrive 云存储空间、高级安全性等结合在一起,可帮助你在任何设备上完成操作。

    5 引用 • 34 回帖 • 1 关注
  • Vditor

    Vditor 是一款浏览器端的 Markdown 编辑器,支持所见即所得、即时渲染(类似 Typora)和分屏预览模式。它使用 TypeScript 实现,支持原生 JavaScript、Vue、React 和 Angular。

    372 引用 • 1857 回帖 • 1 关注
  • CodeMirror
    2 引用 • 17 回帖 • 168 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    497 引用 • 934 回帖 • 1 关注
  • 脑图

    脑图又叫思维导图,是表达发散性思维的有效图形思维工具 ,它简单却又很有效,是一种实用性的思维工具。

    32 引用 • 99 回帖
  • 域名

    域名(Domain Name),简称域名、网域,是由一串用点分隔的名字组成的 Internet 上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。

    44 引用 • 208 回帖
  • FreeMarker

    FreeMarker 是一款好用且功能强大的 Java 模版引擎。

    23 引用 • 20 回帖 • 464 关注
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    89 引用 • 1251 回帖 • 393 关注
  • danl
    175 关注
  • 链书

    链书(Chainbook)是 B3log 开源社区提供的区块链纸质书交易平台,通过 B3T 实现共享激励与价值链。可将你的闲置书籍上架到链书,我们共同构建这个全新的交易平台,让闲置书籍继续发挥它的价值。

    链书社

    链书目前已经下线,也许以后还有计划重制上线。

    14 引用 • 257 回帖 • 2 关注
  • HTML

    HTML5 是 HTML 下一个的主要修订版本,现在仍处于发展阶段。广义论及 HTML5 时,实际指的是包括 HTML、CSS 和 JavaScript 在内的一套技术组合。

    108 引用 • 295 回帖 • 2 关注
  • 以太坊

    以太坊(Ethereum)并不是一个机构,而是一款能够在区块链上实现智能合约、开源的底层系统。以太坊是一个平台和一种编程语言 Solidity,使开发人员能够建立和发布下一代去中心化应用。 以太坊可以用来编程、分散、担保和交易任何事物:投票、域名、金融交易所、众筹、公司管理、合同和知识产权等等。

    34 引用 • 367 回帖 • 1 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    947 引用 • 1460 回帖 • 1 关注
  • 阿里巴巴

    阿里巴巴网络技术有限公司(简称:阿里巴巴集团)是以曾担任英语教师的马云为首的 18 人,于 1999 年在中国杭州创立,他们相信互联网能够创造公平的竞争环境,让小企业通过创新与科技扩展业务,并在参与国内或全球市场竞争时处于更有利的位置。

    43 引用 • 221 回帖 • 58 关注