汎用の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
誰がそれを修正する理由と方法を教えてもらえますか?
Item
(型引数なし)は raw型 であるため、
任意の種類のItem
を_Item.compareTo
_に渡すことができます。たとえば、これはコンパイルします:
_new Item<String>().compareTo(new Item<Integer>())
_
メソッド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());
}
}
_
クラス定義で未加工の型を使用しています(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());
}
これはもっと理にかなっていると思います。私は以下をコンパイルしてテストしました:
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メソッドが必要になったことに注意してください。