Java范型之T extends Comparable<? super T>
在观察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>的更多相关文章
- Java泛型的应用——T extends Comparable<? super T>
在观察Java源码的时候,发现了这么一个写法T extends Comparable<? super T>.不禁纳闷为什么要这么写呢?有什么好处吗,extends和super在这里的作用着 ...
- 如何理解 Java 中的 <T extends Comparable<? super T>>
Java 中类似 <T extends Comparable<? super T>> 这样的类型参数 (Type Parameter) 在 JDK 中或工具类方法中经常能看到. ...
- Java范型随笔
最近在帝都好无聊啊, 排遣寂寞就只有让自己不要停下来,不断的思考了 QWQ; 最近做ndk, java有点忘了,突然看到了一些java范型方面的问题, 踌躇了一会, 想着想着,决定还是写个随笔记录下来 ...
- <T extends Comparable<? super T>>什么意思
<T extends Comparable<? super T>>首先这是运用了java的泛型①extends后面跟的类型如<任意字符 extends 类/接口>表 ...
- <T extends Comparable<? super T>>
在看Collections源代码中,看到如下代码: public static <T extends Comparable<? super T>> void sort(List ...
- 如何理解<T extends Comparable<? super T>>
在看java容器类的时候经常可以看到<T extends Comparable<? super T>>,感觉十分不解? 我们觉得<T extends Comparable ...
- Java范型
泛型不用考虑对象的具体类型.优点在于,因为不用考虑对象的具体类型所以可以对一类对象执行一定的相同操作:缺点在于,因为没有考虑对象的具体类型所以就不能使用对象自带的接口函数.泛型的最佳用同是实现容器类. ...
- Java范型学习笔记
对于范型的使用或者说印象只有集合,其他地方即使使用过也不知道,反正就是只停留在List<E> Map<K, V>,最近刚好闲来无事,就找找资料学习一下:下列为个人学习总结,欢迎 ...
- Java泛型 PECS(Producer Extends, Consumer Super)
本文转载自ImportNew,原文链接 Java 泛型: 什么是PECS(Producer Extends, Consumer Super) PECS指“Producer Extends,Consum ...
随机推荐
- Java开发新手经常遇到的一些问题
A:java.lang.UnsupportedClassVersionError: Bad version number in .class file 解答:导致此问题的原因是Tomcat运行的JDK ...
- java实现双向循环链表
java实现循环链表:http://www.cnblogs.com/lixiaolun/p/4643911.html 在单链表中,查询下一个元素的时间是O(1).查询上一个元素的时间却是O(n). 为 ...
- android:ViewPager动画总结
设置动画的方案: 我们能够使用ViewPager的setPageTransformer方法,为ViewPager设置动画.下面是几种常见动画的演示及效果: 1.CubeInTransformer wa ...
- python发送QQ邮箱方法
import smtplib from email.mime.text import MIMEText mail_user = "user1@qq.com" mail_pwd = ...
- javascript 的继承实例
shape.prototype = { getEdge:function(){ return this.edge; }, getArea:function(){ return this.a*this. ...
- linux内核——会话、进程组、线程组
会话.进程组.线程组总体关系示意图 待插入 Session(会话)与进程组 Shell 分前后台来控制的不是进程而是作业(Job)或者进程组(Process Group).一个前台作业可以由多个进程组 ...
- PHP位运算符(转)
例子 名称 结果 $a & $b And(按位与) 将在 $a 和 $b 中都为 1 的位设为 1. $a | $b Or(按位或) 将在 $a 或者 $b 中为 1 的位设为 1. $a ^ ...
- 委托与事件代码详解与(Object sender,EventArgs e)详解
委托与事件代码详解 using System;using System.Collections.Generic;using System.Text; namespace @Delegate //自定义 ...
- EF性能
批量操作时,加上这句:Context.Configuration.AutoDetectChangesEnabled = false; 主要是取消跟踪,缩短对象添加到上下文的时间(非执行SQL的时间)
- 【python下使用OpenCV实现计算机视觉读书笔记1】输入输出
说明: 该部分内容为<OpenCV Computer Vision with Python>读书笔记. 1.读入文件与保存. import cv2 image=cv2.imread('a. ...