在观察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. 走进C++程序世界------异常处理

    一. 概述 C++自身有着很强的纠错能力,发展到现在,已经建立了比較完好的异常处理机制. C++的异常情况无非两种,一种是语法错误.即程序中出现了错误的语句,函数.结构和类,致使编译程序无法进行.还有 ...

  2. CSS中:before和:after选择器的用法

    在线演示这次给大家带来的是对话气泡效果,主要是演示了 :before / :after 和 border 的用法,赶快来围观吧. 阅读原文:CSS中:before和:after选择器的用法

  3. Samba简单教程+Samba中文显示问题

    1.检测安装Samba服务(1).检查Samba服务包是否已安装:rpm -qa | grep samba(2).如未安装,则插入第一张安装盘,执行:mount /mnt/cdromcd /cdrom ...

  4. centos安装问题集合

    1.版本选择可能直接打开www.centos.org打不开,但是可以打开http://wiki.centos.org/zh/Download,直接找到centos下载列表, (1)i386:支持32位 ...

  5. Discuz常见小问题-如何快速清除帖子

    看别人发的垃圾帖,然后鼠标移到用户名上面,在弹出菜单中点击禁止用户   设置禁止访问-全选所有,删除   然后短期内无法看到效果,帖子还在,你点进去会报错说指定的主题不存在   过三十分钟再刷新页面, ...

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

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

  7. java记录linux top命令信息

    import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.Fi ...

  8. 用sqldevelop进行连接linux中ret Hat 6.2 中的oracle步骤

    1.下载Oracle Instant Client (32-bit) 因为PL/SQL只支持32位的Oracle,所以必须下载对应的32位的才可以. 只需要下载instantclient-basic- ...

  9. HBase源代码分析之HRegionServer上MemStore的flush处理流程(一)

    在<HBase源代码分析之HRegion上MemStore的flsuh流程(一)>.<HBase源代码分析之HRegion上MemStore的flsuh流程(二)>等文中.我们 ...

  10. Android API之android.view.View.MeasureSpec

    android.view.View.MeasureSpec MeasureSpec是View的内部类 public static class MeasureSpec MeasureSpec封装从par ...