简体   繁体   English

泛型之间的区别 <T extends Number & Comparable<T> &gt;和T扩展可比 <? extends Number>

[英]Difference between generics <T extends Number & Comparable<T>> and T extends Comparable<? extends Number>

Can someone explain the difference between <T extends Number & Comparable<T>> and T extends Comparable<? extends Number> 有人可以解释<T extends Number & Comparable<T>>T extends Comparable<? extends Number>之间的区别T extends Comparable<? extends Number> T extends Comparable<? extends Number> ? T extends Comparable<? extends Number>

These look similar to me and both of them compiles fine for sub classes type. 这些看起来与我相似,并且都可以针对子类类型进行编译。 The invalid type args shows below error 无效的类型args显示以下错误

Type parameter is not within bound parameter;should implement 'java.lang.Number' 类型参数不在绑定参数内;应实现“ java.lang.Number”

and

Type parameter is not within bound parameter; 类型参数不在绑定参数内; should extend 'java.lang.Comparable>' 应该扩展'java.lang.Comparable>'

respectively. 分别。

You won't be able to use: 您将无法使用:

Comparable<? extends Number>

because the only methods defined by Comparable are consumers (in the sense of PECS ): it needs to accept instances of type ? extends Number 因为Comparable定义的唯一方法是使用者 (就PECS而言 ):它需要接受type的实例? extends Number ? extends Number into its compareTo method - and there is no type which satisfies that bound safely. ? extends Number到其compareTo方法中-没有满足安全绑定要求的类型。

Integer is a Comparable<? extends Number> Integer是可Comparable<? extends Number> Comparable<? extends Number> , but so is Double . Comparable<? extends Number> ,但Double也是如此。 Thus, you can't safely call instance1.compareTo(instance2) because it would fail if these instances are concretely Integer and Double respectively, since Integer.compareTo can only accept Integer parameters. 因此,您不能安全地调用instance1.compareTo(instance2)因为如果这些实例分别具体为IntegerDouble ,则它将失败,因为Integer.compareTo仅可以接受Integer参数。

As such, the compiler prevents you from calling this method in the first place. 因此,编译器会阻止您首先调用此方法。

Option 1: 选项1:

public class A <T extends Number & Comparable<T>>{}

Your Generic Parameter should extend Number and implements Comparable, which means class A is a Number and Comparable. 您的通用参数应该扩展Number 实现Comparable,这意味着A类是Number and Comparable。

Option 2: 选项2:

public class B <T extends Comparable<? extends Number>>{}

T is Comparable on Numbers(can compare Number only) but doesn't have to be a Number, unlike option 1 T与数字可比(只能比较数字),但不必是数字,与选项1不同

I will explain by example: 我将举例说明:

A 一种

public class A <T extends Number & Comparable<T>>{}

B

public class B <T extends Comparable<? extends Number>>{}

IntegerWrapper (Option 2) IntegerWrapper (选项2)

    public class IntegerWrapper implements Comparable<Integer>  {

      Integer number;

      public IntegerWrapper(int number) {
        this.number = number;
      }

      @Override
      public int compareTo(Integer o) {
        return number.compareTo(o);
      }
    }

GenericsTest public class GenericsTest { GenericsTest公共类GenericsTest {

  public static void main(String args[]){
    A myA = new A<Integer>();

    B myB = new B<IntegerWrapper>();
  }
}

I think option 1 is what you are looking for, because i can't think of many useful scenarios for Option 2(Maybe there is...) 我认为选项1是您要寻找的,因为我想不出选项2的许多有用方案(也许有...)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM