Java 的泛型是如何工作的?

How does Java's generics work?

谁能帮我理解 Java 的泛型是如何工作的?我理解它的概念。但是对于这个具体的代码示例,我并不清楚编译器的错误信息。

示例代码: 测试class

// Test code 
public class A < ListType extends Comparable < ListType >> {
// To make the instance variable y
public int y;
// To make the instance variable s
public String s;

//Constructor Method
public A(int requiredY, String requiredS) {
y = requiredY;
s = requiredS;
}

more code here...
}

然后在不同的class我写了

List <A> a = new ArrayList<A>();
more code here...
Collections.sort(a)

我收到的错误消息是

test.java:20: error: no suitable method found for sort(List<A>)
Collections.sort(a);
           ^
method Collections.<T#1>sort(List<T#1>) is not applicable
  (inference variable T#1 has incompatible bounds
    equality constraints: A
    upper bounds: Comparable<? super T#1>)
method Collections.<T#2>sort(List<T#2>,Comparator<? super T#2>) is not applicable
  (cannot infer type-variable(s) T#2
    (actual and formal argument lists differ in length))

其中 T#1、T#2 是类型变量:

T#1 extends Comparable<? super T#1> declared in method <T#1>sort(List<T#1>)
T#2 extends Object declared in method <T#2>sort(List<T#2>,Comparator<? super T#2>)

我不明白为什么编译器会抱怨类型参数。集合不应该起作用吗?因为类型参数都是可以相互比较的。

您应该检查如何使用 Comparator Interface

要比较自定义 类 你需要实现你自定义的比较器,然后你才能使用集合接口提供的排序方法。

大家可以参考一下here

您的问题是 A 不是 Comparable。注意你的类型签名:

public class A<ListType extends Comparable<ListType>>

这表示 A(这是具体 class 的糟糕名称,单字母类型通常为泛型类型保留)具有泛型类型 ListType,并且ListTypeComparable 与其他 ListType 个对象。

Collections.sort() 的签名期望传递 List<T>,其中 T 是实现 Comparable 的通用类型。因为 A 没有实现 Comparable 你不能把它传递给 Collections.sort().

您可能并不打算按照您的方式定义 A。您可能打算做这样的事情:

public class A<ListType> implements Comparable<A<ListType>>

这表示 A 有一个名为 ListType 的通用类型,并且 A 实现了 Comparable,因此可以与其他实例进行比较(和排序) A.

因为 A 现在实现了 Comparable 接口,你需要定义一个 compareTo() A.

方法

要么您为了隐藏 class 名称而写错了问题,或者您错误地表示了泛型。

如果你想做的是制作一个可以排序的 class,你可以在 class A 正如其他人所建议的那样。

public class A < ListType extends Comparable < ListType >> {
...
}

上面的代码需要 class A 接受 extends/implements Comparable 的 class,并使用 ListType 作为其类型擦除。 由于您没有说明如何使用 ListType 来绑定类型,因此我认为这不是您想要的。

通常泛型用于绑定您可以在 class 中使用的参数类型,以便在编译时提供类型安全的操作。

import java.lang.Override;
public class A <ListType extends Comparable<ListType>>{
    ListType lt;
    A(ListType b){
        this.lt = b;
    }
    static class B implements Comparable<B>{
        B(){};
        @Override
        public int compareTo(B b){
            return 0;
        }
    }
    static class C implements Comparable<B>{
        C(){};
        @Override
        public int compareTo(B c){
            return 0;
        }
    }


    public static void main(String[] args){
        A<B> a = new A<B>(new B());   //OK
        A<C> _a = new A<C>(new C()); //ERROR: is not within bound
        System.out.println("");
    }
}

因为 class C 本身没有实现 Comparable class,所以不能将 class C 变量传递给 class A 构造函数。 如果你想创建一个类型来接受任何扩展 Comparable 的 classes,你可以使用通配符 ?.

public class A <ListType extends Comparable<?>>

或使用单个大写字母作为类型以获得更好的代码样式

public class A <T extends Comparable<?>>