Java的泛型如何工作?

时间:2016-04-20 02:59:31

标签: java generics collections comparable

有人可以帮我理解Java的仿制药是如何工作的吗?我理解它的概念。但是对于代码的这个特定示例,我并不清楚地理解编译器的错误消息。

示例代码: 测试类

// 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...
}

然后在另一个班级我写了

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>)

我不明白为什么编译器会抱怨type参数。收藏品不应该有效吗?因为类型参数是相互可比的。

3 个答案:

答案 0 :(得分:1)

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

public class A<ListType extends Comparable<ListType>>

这表示A(对于具体类来说是一个糟糕的名称,单字母类型通常是为泛型类型保留的)具有泛型类型ListType,而ListType Comparable与其他ListType个对象。

Collections.sort()的签名期望传递List<T>,其中T是实现Comparable的通用类型。由于A未实现Comparable,因此您无法将其传递给Collections.sort()

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

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

这表示A具有名为ListType的通用类型,而A实现Comparable,因此可以与{{1}的其他实例进行比较(和排序) 1}}。

由于A现在实现了Comparable接口,因此您需要定义一个 A上的compareTo()方法。

答案 1 :(得分:1)

你要么把你的问题写错了,以便隐藏类名,要么你错误地代表了泛型。

如果你要做的是制作一个可以分类的课程,你可以在其他人建议的课程 A 中实施Comparable

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

上述代码要求class A接受扩展/实现Comparable的类,并使用ListType作为其类型擦除。 既然你没有展示如何使用ListType绑定一个类型,我认为这不是你想要的。

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

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 C变量传递给class A构造函数。 如果要创建一个可以接受任何扩展Comparable的类的类型,可以使用通配符?

public class A <ListType extends Comparable<?>>

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

public class A <T extends Comparable<?>>

答案 2 :(得分:0)

您应该检查如何使用Comparator Interface

要比较实现自定义Comparator所需的自定义类,然后只能使用集合界面提供的排序方法。

您可以查看here以供参考。