对 <T extends Number & Comparable<? super T>> 的理解

今天复习泛型的时候看到这样一段代码

    private static <T extends Number & Comparable<? super T>> T min(T[] values){  // 传入的实参类型必须Number的子类,且实参或者实参的父类必须实现了 Comparable接口,
        if(values == null || values.length == 0){
            return null;
        }
        T min = values[0];
        for(int i = 1; i < values.length; i++){
            if(min.compareTo(values[i]) > 0){
                min = values[i];
            }
        }

        return min;
    }

上面的泛型声明确实是十分复杂,<T extends Number & Comparable<? super T>其实是由下面两部分组成

<T extends Number>   

<T extends Comparable<? super T>>

第一个泛型声明表示 实参类型必须是 Number 或者Number 的子类,这个比较好理解

第二个泛型声明表示 实参类型必须是 实现了Comparable 接口或者其父类实现了Comparable 接口,假设 Dog 类继承了 Animal 类,如果Animal 没有实现 Comparable 接口,但是Dog 类自己实现了,那么Dog 类可以作为这个函数的泛型类型实参,如果 Dog 没有直接实现 Comparable 接口,但是它的父类 Animal 实现了,Dog 类也可以作为泛型类型的实参,因为Dog 自己虽然没有 重写CompareTo()方法,但是它的父类重写了,它可以调用父类的Comparable 方法。说到这里应该很明白了如果用的是 <T extends Comparable<? super T>> 那么只要实参类型或实参类型的父类实现了 Comparable 接口,那 这个实参类型就可以用这个方法,而如果 用的是 <T extends Comparable<T>> 声明泛型的话,只有当实参类型实现了 Comparable 接口,他才可以使用这个方法,就算它的父类实现这个方法也不行。

如下面这段代码:虽然 MyNumberSon 类的父类 MyNumberFather 实现了 Comparable 接口,但是因为采用的是 <T extends Comparable<T>> 的泛型声明方式,所以 MyNumberSon 还是不能使用这个 min() 方法

class MyNumberFather extends Number implements Comparable<MyNumberFather>{
    @Override
    public int compareTo(MyNumberFather o) {
        return 0;
    }

    @Override
    public int intValue() {
        return 0;
    }

    @Override
    public long longValue() {
        return 0;
    }

    @Override
    public float floatValue() {
        return 0;
    }

    @Override
    public double doubleValue() {
        return 0;
    }
}

MyNumberSon 类

class MyNumberSon extends MyNumberFather{
    @Override
    public int compareTo(MyNumberFather o) {
        return 0;
    }
}

上面的 min() 函数将泛型声明做些改动,改成下面这种形式

    private static <T extends Number & Comparable<T>> T min(T[] values){
        if(values == null || values.length == 0){
            return null;
        }
        T min = values[0];
        for(int i = 1; i < values.length; i++){
            if(min.compareTo(values[i]) > 0){
                min = values[i];
            }
        }

        return min;
    }

那么如果在主函数中调用 min (), 则会有编译错误

但是如果使用的 <T extends Comparable<? super T>> 则不会报错。

 总结:

如果用的是 <T extends Comparable<? super T>> 那么只要实参类型或实参类型的父类实现了 Comparable 接口,那 这个实参类型就可以用这个方法,

而如果 用的是 <T extends Comparable<T>> 声明泛型的话,只有当实参类型实现了 Comparable 接口,他才可以使用这个方法,就算它的父类实现这个方法也不行。

<T extends Comparable<? Super T>> 相比于 <T extends Comparable<T>> 有更好的通用性。

原文地址:https://www.cnblogs.com/hi3254014978/p/12613053.html