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

我们觉得<T extends Comparable<T>>我们是知道的,T是实现了Comparable接口的类型,因此他们之间可以进行比较,

<? super T>表名类型参数需要是T或T的父类,那么<T extends Comparable<? super T>>到底是什么意思呢?

对T的约束是Comparable的子类,对Comparable中泛型的约束是,?至少是T的父类,那么就意味着T是?的子类。

一言以蔽之:元素必须是实现了Comparable接口的类或者其子类,可以使用父类方法比较子类型

  1. /**
  2. * Created by wangbin10 on 2018/9/18.
  3. * mySort2() list中的元素必须是实现了Comparable接口的类或者其子类
  4. * Java采取的是类型擦除的方法来实现泛型,并通过extends和super关键字来约束泛型的上界和下界。
  5. * extends关键字用于确定泛型的上界。<A extends B>表示类B或者其子类。
  6. * super关键字用于确定泛型的下界,<A super B>表示类B或者其父类,一直到Object。?则是一个通配符。
  7. * 因此,<T extends Comparable<? super T>>表示了上界为实现了Comparable接口的类,<? super T>则表示实现Comparable接口的类的子类也可以,从而确定下界
  8. */
  9. public class Test {
  10. public static void main(String[] args) {
  11. List<Animal> animals = new ArrayList<>();
  12. animals.add(new Animal(25));
  13. animals.add(new Dog(34));
  14. mySort1(animals);//ok
  15.  
  16. List<Dog> dogs = new ArrayList<>();
  17. dogs.add(new Dog(18));
  18. dogs.add(new Dog(19));
  19. /**
  20. * 这个编译不能通过,因为T推断是Animal,得到的是Dog,Dog没有实现Comparable,所以不行
  21. * mySort1(dogs);
  22. * */
  23.  
  24. mySort2(animals);//ok
  25. mySort2(dogs);//ok
  26. }
  27.  
  28. /**
  29. * mySort1的类型参数是T extends Comparable<T>,他要求T必须实现Comparable
  30. * @param list
  31. * @param <T>
  32. */
  33. public static <T extends Comparable<T>> void mySort1(List<T> list) {
  34. Collections.sort(list);
  35. System.out.println("mySort1 Success!");
  36. }
  37.  
  38. /**
  39. * list中的元素必须是实现了Comparable接口的类或者其子类
  40. * @param list
  41. * @param <T>
  42. */
  43. public static <T extends Comparable<? super T>> void mySort2(List<T> list) {
  44. Collections.sort(list);
  45. System.out.println("mySort2 Success!");
  46.  
  47. }
  48. }
  49.  
  50. class Animal implements Comparable<Animal> {
  51. int age;
  52.  
  53. public Animal(int age) {
  54. this.age = age;
  55. }
  56.  
  57. @Override
  58. public int compareTo(Animal o) {
  59. return Integer.compare(this.age, o.age);
  60. }
  61. }
  62.  
  63. /**
  64. * Dog根本不能implements Comparable<Dog>,因为这样就会实现两个相同的接口
  65. */
  66. class Dog extends Animal {
  67. public Dog(int age) {
  68. super(age);
  69. }
  70. }

如何理解<T extends Comparable<? super T>>的更多相关文章

  1. 如何理解<base href="<%=basePath%>" ---转载

    原文链接http://316325524.blog.163.com/blog/static/6652052320111118111620897/ "base href " 今天在写 ...

  2. 如何理解<base href="<%=basePath%>"

    原文链接http://316325524.blog.163.com/blog/static/6652052320111118111620897/ "base href " 今天在写 ...

  3. <base href="<%=basePath%>

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  4. JSP中<base href="<%=basePath%>">作用

    通常在JSP页面开通有如下代码: <% String path = request.getContextPath(); String basePath = request.getScheme() ...

  5. JSP页面中 <base href="<%=basePath%>">

    base标记是一个基链接标记,是一个单标记.用以改变文件中所有连结标记的参数内定值.它只能应用于标记<head>与</head>之间.你网页上的所有相对路径在链接时都将在前面加 ...

  6. 当使用了相对路径 <base href="<%= basePath %>" /> 后,全局都只能使用相对路径

    <% String path = request.getContextPath(); String basePath = request.getScheme() + "://" ...

  7. JSP中<base href="<%=basePath%>">的作用

    来源于:http://fanshuyao.iteye.com/blog/2097229 首先了解是什么是<base href=""> <base href=&qu ...

  8. [Angular2 Router] Understand the Angular 2 Base href Requirement

    The <base href=”/”/> you define will determine how all other assets you plan on loading treat ...

  9. window.location.href = basePath + "paper/deleteExpertComment.action?expertId="+$(this).prev().val();

    window.location.href = basePath + "paper/deleteExpertComment.action?expertId="+$(this).pre ...

  10. 深入理解Oracle的并行操作-转载

    转载:http://czmmiao.iteye.com/blog/1487568 并行(Parallel)和OLAP系统 并行的实现机制是:首先,Oracle会创建一个进程用于协调并行服务进程之间的信 ...

随机推荐

  1. java读取Properties文件及赋值

    懒得整理了,直接复制我工程里的代码: 第一个读取文件的类可以直接复制, 不复制的话,在下面取值和赋值部分的代码new EmailProperRead(systemType).properties根据自 ...

  2. PAT 1031-1040 题解

    早期部分代码用 Java 实现.由于 PAT 虽然支持各种语言,但只有 C/C++标程来限定时间,许多题目用 Java 读入数据就已经超时,后来转投 C/C++.浏览全部代码:请戳 本文谨代表个人思路 ...

  3. 关于js的window.open()

    window.open是javascript函数,该函数的作用是打开一个新窗口或这改变原来的窗口,不过一般用来的是打开新窗口,因为修改原来的网页地址,可以有另一个函数,那就是window.locati ...

  4. Extensible File System

    An extensible file system format for portable storage media is provided. The extensible file system ...

  5. Mac下cocos2dx3.1用Cocos IDE写的Lua binding篇01

    本人Lua新手,写着玩玩. 新建一个模版project. 一.改动main.lua require "Cocos2d" require "Cocos2dConstants ...

  6. 有关C++中String的一些知识

    在C++中,String 是一个类,相当于其他简单的类一样,它之中也包含很多简单的处理字符串的函数. 具体见 已下载好的String 类的基本操作 PDF.(大学那点事)

  7. WPF 曲线图表控件(自制)(一)

    原文:WPF 曲线图表控件(自制)(一) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/koloumi/article/details/775092 ...

  8. Blend_ControlTemplate(Z)

    原文:Blend_ControlTemplate(Z) 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010265681/article/deta ...

  9. HDU2665 Kth number 【合并树】

    Kth number Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Tota ...

  10. Ant—使用Ant构建一个简单的Java工程(两)

    博客<Ant-使用Ant构建一个简单的Java项目(一)>演示了使用Ant工具构建简单的Java项目,接着这个样例来进一步学习Ant: 上面样例须要运行多条ant命令才干运行Test类中的 ...