如何在Java中对泛型类型设置限制?

46

我有一个通用的类:

public class ListObject<T>
{
    // fields
    protected T _Value = null;
      // ..
}

现在我想要做类似如下的事情:
ListObject<MyClass> foo = new ListObject<MyClass>();
ListObject<MyClass> foo2 = new ListObject<MyClass>();
foo.compareTo(foo2);

问题:

如何针对泛型 T 定义 compareTo() 方法?

我猜想我必须在泛型 T 上实现某种约束,以告诉它 T 实现了一个特定的接口(也许是 Comparable,如果该接口存在)。

有人能提供一个小的代码示例吗?

4个回答

58

请阅读此处的讨论:Java中的泛型和排序

简短回答,你能得到的最好结果是:

class ListObject<T extends Comparable<? super T>> {
    ...
}

但也有理由仅使用:
class ListObject<T extends Comparable> {
    ...
}

1
我暂时会坚持使用ListObject<T extends Comparable>。 - citronas
3
还要检查相关的线程:https://dev59.com/b0vSa4cB1Zd3GeqPdVLy#2072820,其中讨论了形式为<? super T>的通配符的必要性。 - sateesh

5

这取决于您希望compareTo方法做什么。只需定义compareTo方法以接受其他ListObject<T>值,可以通过以下方式完成:

public class ListObject<T> {
  public int compareTo(ListObject<T> other) {
    ...
  }
}

然而,如果您想在该参数上实际调用方法,则需要添加一些约束条件,以提供有关T值的更多信息,如下所示

class ListObject<T extends Comparable<T>> {
  ...
}

3
尝试使用public class ListObject<T extends U>。只有实现 U(或派生自 U)的T才能被允许替换。

给我编译器错误。 即使是这样一个简单的TestClass:public class ConstraintTest<T implements Comparable> { }语法错误,标记“implements”,期望我错过了什么? - citronas
@citronas:即使是接口,实际上也要使用“extends”。请注意,如果您使用具有“extends”属性的基类,则可以直接将基类添加到泛型对象中,这是泛型扩展的最大(也是最糟糕的)副作用。 - Esko

-3
public class ListObject<T implements Comparable> {...}

4
因为Comparable没有类型参数,所以它是原始类型,在Java 1.5+中不应该使用。被投票否决了(-1)。 - helpermethod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接