Java泛型的应用:T extends Comparable? super T

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

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

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

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

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

import java.util.*;
class Demo<T extends List>{}
public class Test
{
   
public static void main(String[] args) {
    Demo
<ArrayList> p = null; // 编译正确
//这里因为ArrayList是List的子类所以通过
//如果改为Demo<Collection> p = null;就会报错这样就限制了上限
    }
}

在理解了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这个类为例。

  代码如下所示:

import java.util.GregorianCalendar;
class Demo<T extends Comparable<T>>{}
//注意这里是没有? super的
public class Test
{
   
public static void main(String[] args) {
      Demo
<GregorianCalendar> p = null;
        }
}

  这里编译报错,因为这里的<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为例。代码如下所示:

import java.util.GregorianCalendar;

class Demo<T extends Comparable<? super T>>{}

public class Test1
{
   
public static void main(String[] args) {
      Demo
<GregorianCalendar> p = null; // 编译正确
    }
}
  

 

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

 

  3. 实例代码演示

  代码如下所示:

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
 
public class Test
{
   
//第一种声明:简单,灵活性低
    public static <T extends Comparable<T>> void mySort1(List<T> list)
    {
        Collections.sort(list);
    }

   
//第二种声明:复杂,灵活性高
    public static <T extends Comparable<? super T>> void mySort2(List<T> l)
    {
        Collections.sort(list);
    }

   
public static void main(String[] args)
    {
       
//主函数中将分别创建Animal和Dog两个序列,然后调用排序方法对其进行测试

     //main函数中具体的两个版本代码将在下面具体展示


    }
}

class Animal implements Comparable<Animal>
{
   
protected int age;

   
public Animal(int age)

    {
       
this.age = age;
    }

   
//使用年龄与另一实例比较大小
    @Override
   
public int compareTo(Animal other)
    {
       
return this.age - other.age;
    }
}

class Dog extends Animal
{
   
public Dog(int age)
    {
       
super(age);
    }
}

上面的代码包括三个类:

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

Dog从Animal继承,为其子类。

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

mySort1()使用<T extends Comparable<T>>类型参数

mySort2()使用<T extends Comparable<? super T>>类型参数

main()测试方法。在这里将分别创建Animal和Dog两个序列,然后调用排序方法对其进行测试。

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

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/9939ca355c8df3fdb1c8a95bb4b856d5.html