在观察Java源码的时候,发现了这么一个写法T extends Comparable<? super T>。不禁纳闷为什么要这么写呢?有什么好处吗,extends和super在这里的作用着实让人有点不清楚。

接下来,我将结合代码跟大家分享一下我关于这里泛型应用的看法。

1.<T extends Comparable<? super T>>代表什么意思

  • 大家可以明白的是这里应用到了Java的泛型,那么首先向大家说明一下这里extends的作用

extends后面跟的类型,如<任意字符 extends 类/接口>表示泛型的上限。示例代码如下:

  • 在理解了extends所表示的泛型的上限后,接下来介绍一下super的作用,它与extends相反,表示的是泛型的下限。
  • 所以结合上述两点,我们来分析一下这句话整体代表什么意思。首先,extends对泛型上限进行了限制即T必须是Comparable<? super T>的子类,然后<? super T>表示Comparable<>中的类型下限为T!

2. <T extends Comparable<T>> 和 <T extends Comparable<? super T>> 有什么不同

接下来我们通过对比,使得大家对为何要这样编写代码有更加深刻的印象。

  • <T extends Comparable<T>>

它代表的意思是:类型T必须实现Comparable接口,并且这个接口的类型是T。这样,T的实例之间才能相互比较大小。这边我们以Java中GregorianCalendar这个类为例。

代码如下所示:

这里编译报错,因为这里的<T extends Comparable<T>>相当于<GregorianCalendar extends Comparable<GregorianCalendar>>,但是GregorianCalendar中并没有实现Comparable<GregorianCalendar>,而是仅仅持有从Calendar继承过来的Comparable<Calendar>,这样就会因为不在限制范围内而报错。

  • <T extends Comparable<? super T>>

它代表的意思是:类型T必须实现Comparable接口,并且这个接口的类型是T或者是T的任一父类。这样声明后,T的实例之间和T的父类的实例之间可以相互比较大小。同样还是以GregorianCalendar为例。代码如下所示:

此时编译通过,这里可以理解为<GregorianCalendar extends Comparable<Calendar>>!因为Calendar为GregorianCalendar 的父类并且GregorianCalendar 实现了Comparable<Calendar>,具体可以在API中进行查看!

3. 实例代码演示

代码如下所示:

上面的代码包括三个类:

1. Animal实现了Comparable<Animal>接口,通过年龄来比较实例的大小

2. Dog从Animal继承,为其子类。

3. Test类中提供了两个排序方法和测试用的main()方法:

  • mySort1()使用<T extends Comparable<T>>类型参数
  • mySort2()使用<T extends Comparable<? super T>>类型参数
  • main()测试方法。在这里将分别创建Animal和Dog两个序列,然后调用排序方法对其进行测试。

3.1 对mySort1()进行测试,main方法代码如下所示:

结果编译出错,报错信息为:

mySort1() 方法的类型参数是<T extends Comparable<T>>,它要求的类型参数是类型为T的Comparable。

如果传入的是List<Animal>程序将正常执行,因为Animal实现了接口Comparable<Animal>。

但是,如果传入的参数是List<Dog>程序将报错,因为Dog类中没有实现接口Comparable<Dog>,它只从Animal继承了一个Comparable<Animal>接口。

注意:animals list中实际上是包含一个Dog实例的。如果碰上类似的情况(子类list不能传入到一个方法中),可以考虑把子类实例放到一个父类 list 中,避免编译错误。

3.2 对mySort12()进行测试,main方法代码如下所示:

这时候我们发现该程序可以正常运行。它不但能够接受Animal implements Comparable<Animal>这样的参数,也可以接收:Dog implements Comparable<Animal>这样的参数。

3.3 是否可以通过将Dog实现Comparable<Dog>来解决问题?

由分析可得程序出现问题是因为Dog类没有实现接口Comparable<Dog>,那么我们能否将该类实现接口Comparable<Dog>来解决问题呢?

代码如下所示:

结果程序编译报错,错误信息如下所示:

意义是Dog类已经从Animal中继承了Comparable该接口,无法再实现一个Comparable。

若子类需要使用自己的比较方法,则需要重写父类的public int CompareTo(Animal other)方法。

4. 总结

对Animal/Dog这两个有父子关系的类来说:<T extends Comparable<? super T>>可以接受List<Animal>,也可以接收 List<Dog> 。而<T extends Comparable<T>>只可以接收 List<Animal>所以,<T extends Comparable<? super T>>这样的类型参数对所传入的参数限制更少,提高了 API 的灵活性。总的来说,在保证类型安全的前提下,要使用限制最少的类型参数。

Java范型之T extends Comparable<? super T>的更多相关文章

  1. Java泛型的应用——T extends Comparable<? super T>

    在观察Java源码的时候,发现了这么一个写法T extends Comparable<? super T>.不禁纳闷为什么要这么写呢?有什么好处吗,extends和super在这里的作用着 ...

  2. 如何理解 Java 中的 <T extends Comparable<? super T>>

    Java 中类似 <T extends Comparable<? super T>> 这样的类型参数 (Type Parameter) 在 JDK 中或工具类方法中经常能看到. ...

  3. Java范型随笔

    最近在帝都好无聊啊, 排遣寂寞就只有让自己不要停下来,不断的思考了 QWQ; 最近做ndk, java有点忘了,突然看到了一些java范型方面的问题, 踌躇了一会, 想着想着,决定还是写个随笔记录下来 ...

  4. <T extends Comparable<? super T>>什么意思

    <T extends Comparable<? super T>>首先这是运用了java的泛型①extends后面跟的类型如<任意字符 extends 类/接口>表 ...

  5. <T extends Comparable<? super T>>

    在看Collections源代码中,看到如下代码: public static <T extends Comparable<? super T>> void sort(List ...

  6. 如何理解<T extends Comparable<? super T>>

    在看java容器类的时候经常可以看到<T extends Comparable<? super T>>,感觉十分不解? 我们觉得<T extends Comparable ...

  7. Java范型

    泛型不用考虑对象的具体类型.优点在于,因为不用考虑对象的具体类型所以可以对一类对象执行一定的相同操作:缺点在于,因为没有考虑对象的具体类型所以就不能使用对象自带的接口函数.泛型的最佳用同是实现容器类. ...

  8. Java范型学习笔记

    对于范型的使用或者说印象只有集合,其他地方即使使用过也不知道,反正就是只停留在List<E> Map<K, V>,最近刚好闲来无事,就找找资料学习一下:下列为个人学习总结,欢迎 ...

  9. Java泛型 PECS(Producer Extends, Consumer Super)

    本文转载自ImportNew,原文链接 Java 泛型: 什么是PECS(Producer Extends, Consumer Super) PECS指“Producer Extends,Consum ...

随机推荐

  1. (转)使用百度 BAE做SVN服务器

    转自:https://www.sinosky.org/bae-svn.html#comment-1775 从这里下载 目前,无论是Windows平台.Linux平台还是Mac平台都有比较成熟的SVN客 ...

  2. [Transducer] Step by Step to build a simple transducer

    Transducers are composable algorithmic transformations. They are independent from the context of the ...

  3. 黑苹果安装 this is an unknown cpu model 0x3a

    一:安装说明 安装的是 mac os x 10.8.3 懒人版: ASUS b75ma 主板 i3 cpu 二:安装出现错误 百度谷歌,各种找原因,各路大神们都说是显卡的问题,因这电源管理只是一个警告 ...

  4. 解压zip,解决中文乱码

    Project p = new Project();        Expand e = new Expand();        e.setProject(p);        e.setSrc(f ...

  5. localhost连接慢如何解决?

    localhost连接慢如何解决 php 环境本地用ip连接mysql响应快, 今天碰到一个连接mysql的怪问题,我在php 环境本地用ip连接mysql响应快,用localhost连接慢,后来百度 ...

  6. Android应用更新自动检测下载

    由于Android项目开源所致,市面上出现了N多安卓软件市场.为了让我们开发的软件有更多的用户使用,我们需要向N多市场发布,软件升级后,我们也必须到安卓市场上进行更新,给我们增加了工作量.因此我们有必 ...

  7. CSS命名规范 BEM

    良好的代码结构,HTML和css元素之间的关系,对于项目交付是很重要的! BEM解释: (1).block 是BEM的区块(B),包含内容和风格.如bootstrap框架的.container. (2 ...

  8. Linux环境下的make和makefile详解

    无论是在Linux还是在Unix环境中,make都是一个非常重要的编译命令.不管是自己进行项目开发还是安装应用软件,我们都经常要用到make或make install.利用make工具,我们可以将大型 ...

  9. Ubuntu分区方案归总

     更新时间:2010-8-26   一.各文件及文件夹的定义 /bin:bin是binary(二进制)的缩写.存放必要的命令  存放增加的用户程序. /bin分区,存放标准系统实用程序. /boot: ...

  10. 14条最佳JS代码编写技巧

    http://gaohaixian.blog.163.com/blog/static/123260105201142645458315/写任何编程代码,不同的开发者都会有不同的见解.但参考一下总是好的 ...