web-dev-qa-db-ja.com

Comparableをジェネリッククラスで実装する

汎用のComparableインターフェースを実装するクラスを定義したい。クラスでは、ジェネリック型要素Tも定義しました。インターフェイスを実装するために、比較をTに委任します。ここに私のコードがあります:

public class Item<T extends Comparable<T>> implements Comparable<Item> {

    private int s;
    private T t;

    public T getT() {
        return t;
    }

    @Override
    public int compareTo(Item o) {
        return getT().compareTo(o.getT());
    }
}

コンパイルしようとすると、次のエラー情報が表示されます。

Item.Java:11: error: method compareTo in interface Comparable<T#2> cannot be applied to given types;
        return getT().compareTo(o.getT());
                     ^
  required: T#1
  found: Comparable
  reason: actual argument Comparable cannot be converted to T#1 by method invocation conversion
  where T#1,T#2 are type-variables:
    T#1 extends Comparable<T#1> declared in class Item
    T#2 extends Object declared in interface Comparable
1 error

誰がそれを修正する理由と方法を教えてもらえますか?

13
frank.liu

Item(型引数なし)は raw型 であるため、

  1. 任意の種類のItemを_Item.compareTo_に渡すことができます。たとえば、これはコンパイルします:

    _new Item<String>().compareTo(new Item<Integer>())
    _
  2. メソッドo.getT()は、Comparableの代わりにTを返します。これにより、コンパイルエラーが発生します。

    最初のポイントの例では、_Item<Integer>_を_Item.compareTo_に渡した後、Integerを誤って_String.compareTo_に渡します。コンパイルエラーにより、それを行うコードを記述できません。

生の型を削除するだけでいいと思います:

_public class Item<T extends Comparable<T>>
implements Comparable<Item<T>> {

    ...

    @Override
    public int compareTo(Item<T> o) {
        return getT().compareTo(o.getT());
    }
}
_
18
Radiodef

クラス定義で未加工の型を使用しています(Item<T>は汎用ですが、型パラメーター<T>は省略しています)、次のように変更します。

class Item<T extends Comparable<T>> implements Comparable<Item<T>>

(最後の<T>に注意してください)

compareToメソッドも同様に変更する必要があります。

public int compareTo(Item<T> o) { // again, use generics
    return getT().compareTo(o.getT());
}
7
Njol

これはもっと理にかなっていると思います。私は以下をコンパイルしてテストしました:

class Item<E extends Comparable<E>> implements Comparable<E> {

 private int s;
 private E t;

 public E getE() {
     return t;
 }

 @Override
 public int compareTo(E e) {
     return getE().compareTo(e);
 }

 public int compareTo(Item<E> other)
    {
        return getE().compareTo(other.getE());
    }

 }

2つのcompareToメソッドが必要になったことに注意してください。

1
aditya