如何理解<T extends Comparable<? super T>>
在看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接口的类或者其子类,可以使用父类方法比较子类型
/**
* Created by wangbin10 on 2018/9/18.
* mySort2() list中的元素必须是实现了Comparable接口的类或者其子类
* Java采取的是类型擦除的方法来实现泛型,并通过extends和super关键字来约束泛型的上界和下界。
* extends关键字用于确定泛型的上界。<A extends B>表示类B或者其子类。
* super关键字用于确定泛型的下界,<A super B>表示类B或者其父类,一直到Object。?则是一个通配符。
* 因此,<T extends Comparable<? super T>>表示了上界为实现了Comparable接口的类,<? super T>则表示实现Comparable接口的类的子类也可以,从而确定下界
*/
public class Test {
public static void main(String[] args) {
List<Animal> animals = new ArrayList<>();
animals.add(new Animal(25));
animals.add(new Dog(34));
mySort1(animals);//ok List<Dog> dogs = new ArrayList<>();
dogs.add(new Dog(18));
dogs.add(new Dog(19));
/**
* 这个编译不能通过,因为T推断是Animal,得到的是Dog,Dog没有实现Comparable,所以不行
* mySort1(dogs);
* */ mySort2(animals);//ok
mySort2(dogs);//ok
} /**
* mySort1的类型参数是T extends Comparable<T>,他要求T必须实现Comparable
* @param list
* @param <T>
*/
public static <T extends Comparable<T>> void mySort1(List<T> list) {
Collections.sort(list);
System.out.println("mySort1 Success!");
} /**
* list中的元素必须是实现了Comparable接口的类或者其子类
* @param list
* @param <T>
*/
public static <T extends Comparable<? super T>> void mySort2(List<T> list) {
Collections.sort(list);
System.out.println("mySort2 Success!"); }
} class Animal implements Comparable<Animal> {
int age; public Animal(int age) {
this.age = age;
} @Override
public int compareTo(Animal o) {
return Integer.compare(this.age, o.age);
}
} /**
* Dog根本不能implements Comparable<Dog>,因为这样就会实现两个相同的接口
*/
class Dog extends Animal {
public Dog(int age) {
super(age);
}
}
如何理解<T extends Comparable<? super T>>的更多相关文章
- 如何理解<base href="<%=basePath%>" ---转载
原文链接http://316325524.blog.163.com/blog/static/6652052320111118111620897/ "base href " 今天在写 ...
- 如何理解<base href="<%=basePath%>"
原文链接http://316325524.blog.163.com/blog/static/6652052320111118111620897/ "base href " 今天在写 ...
- <base href="<%=basePath%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...
- JSP中<base href="<%=basePath%>">作用
通常在JSP页面开通有如下代码: <% String path = request.getContextPath(); String basePath = request.getScheme() ...
- JSP页面中 <base href="<%=basePath%>">
base标记是一个基链接标记,是一个单标记.用以改变文件中所有连结标记的参数内定值.它只能应用于标记<head>与</head>之间.你网页上的所有相对路径在链接时都将在前面加 ...
- 当使用了相对路径 <base href="<%= basePath %>" /> 后,全局都只能使用相对路径
<% String path = request.getContextPath(); String basePath = request.getScheme() + "://" ...
- JSP中<base href="<%=basePath%>">的作用
来源于:http://fanshuyao.iteye.com/blog/2097229 首先了解是什么是<base href=""> <base href=&qu ...
- [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 ...
- window.location.href = basePath + "paper/deleteExpertComment.action?expertId="+$(this).prev().val();
window.location.href = basePath + "paper/deleteExpertComment.action?expertId="+$(this).pre ...
- 深入理解Oracle的并行操作-转载
转载:http://czmmiao.iteye.com/blog/1487568 并行(Parallel)和OLAP系统 并行的实现机制是:首先,Oracle会创建一个进程用于协调并行服务进程之间的信 ...
随机推荐
- VS2017十五项新功能体验
Visual Studio 2017十五项新功能体验 Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP ...
- Go语言并发
Go语言并发机制初探 Go 语言相比Java等一个很大的优势就是可以方便地编写并发程序.Go 语言内置了 goroutine 机制,使用goroutine可以快速地开发并发程序, 更好的利用多核处 ...
- WPF中的Generic.xaml, theme以及custom control
原文:WPF中的Generic.xaml, theme以及custom control 在Visual Studio中创建自定义控件时,所有控件都将添加到/Themes/Generic.xaml. 最 ...
- Android系统联系人全特效实现(下),字母表快速滚动
在上一篇文章中,我和大家一起实现了类似于Android系统联系人的分组导航和挤压动画功能,不过既然文章名叫做<Android系统联系人全特效实现>,那么没有快速滚动功能显然是称不上&quo ...
- Matlab Tricks(十八)—— 矩阵间元素距离的计算
两个矩阵间元素(向量)距离的度量,首先想到的是遍历,循环的方式,显然 matlab 下的编程并不推荐,matlab 下矩阵向量化编程效率尤高. 先考虑两个向量距离的计算: ∥x−y∥2=∥x∥2+∥y ...
- GetEntryAssembly、GetExecutingAssembly和GetCallingAssembly的区别
GetEntryAssembly获取的是当前应用程序第一个启动的程序,一般就是xxx.exe文件. GetExecutingAssembly获取的是当前执行的方法所在的程序文件,可能是.exe,也可能 ...
- python3下的IE自动化模块PAMIE
PAMIE是Python下面的用于IE的自动化模块,支持python2和python3,python3的下载地址:http://sourceforge.net/projects/pamie/files ...
- ubuntu如何修改terminal终端的主机名(修改/etc/hostname文件)
有时候安装完Ubuntu系统后,打开命令终端,终端显示的主机名格式比较难看,例如 我最近买的国内某云的VPS. xxx@VM-1560-ubuntu$ xxx@VM-1560-ubuntu$ 对于有洁 ...
- 用户控件(UserControl)
简介 "用户控件"继承自UserControl,而UserControl继承自ContentControl,也就是内容控件UserControl和Window是一个层次上的,都有x ...
- WPF 控件的内容属性
WPF的内容属性不应定都是content, 例如TextBlock的内容属性是Text Panel的内容属性是Children ListBox的内容属性是Items