web-dev-qa-db-ja.com

Java "生の型Java.lang.ComparableのメンバーとしてのcompareTo(T)への未チェックの呼び出し"

Javaの簡単な練習として、ソートされたリストを実装しようとしています。汎用的にするには、add(Comparable obj)を使用して、Comparableインターフェースを実装する任意のクラスで使用できるようにします。

しかし、コードのどこかでobj.compareTo(...)を使用すると、コンパイラから"unchecked call to compareTo(T) as a member of the raw type Java.lang.Comparable"を取得します(-Xlint:uncheckedオプション)。コードは問題なく動作しますが、その迷惑なメッセージを取り除く方法がわかりません。

ヒントはありますか?

24
3mpty

本質的に、この警告はComparableオブジェクトを任意のオブジェクトと比較できないことを示しています。 Comparable<T>は、ジェネリックインターフェイスです。タイプパラメータTは、このオブジェクトと比較できるオブジェクトのタイプを指定します。

したがって、Comparable<T>を正しく使用するには、次のように、並べ替えられたリストをジェネリックにして、相互に比較できるオブジェクトをリストに格納するという制約を表現する必要があります。

public class SortedList<T extends Comparable<? super T>> {
    public void add(T obj) { ... }
    ...
}
31
axtavt

メソッドパラメータとしてComparableのようなインターフェイスを使用しても、クラスはジェネリックにはなりません。ジェネリック型パラメータを宣言して使用することで、ジェネリックにします。

Quick-n-dirty answer:Comparableは、_Comparable<String>_のような特定の型引数を指定するのではなく、生の型としての汎用インターフェイスです。

これを修正するには、型パラメーターを指定してadd()をジェネリックにします。

_<T extends Comparable<? super T>> add(T obj) { ... }
_

ただし、このクイック修正では、クラスが安全でないという一般的な問題は修正されません。結局のところ、リスト内のすべてのオブジェクトが同じタイプである必要はありませんか?このaddメソッドを使用すると、異なるタイプを同じリストに含めることができます。異種の型を比較しようとするとどうなりますか(compareToObjectインスタンスをNumberインスタンスに、またはStringインスタンスにどうやって)クラスのユーザーに依存して正しいことを行い、リストで1種類のことだけを実行するようにすることができますが、汎用クラスを使用すると、コンパイラーがこのルールを適用できます。

より良いアプローチ:適切な修正は、ソートされたリストクラスがおそらく全体的にジェネリックでなければならないことです、 _Java.util_の他のコレクションクラスと同じように。

あなたはおそらく次のようなものを望みます:

_public class SortedList<T extends Comparable<? super T>>
implements Iterable<T> {
    ...
    public void add(T item) { ... }
    public Iterator<T> iterator() { ... }
    ...
}
_

クラスがジェネリックである場合、addメソッドは独自の正式な型パラメーターを宣言するのではなく、クラスの正式な型パラメーターを使用することに注意してください。

ジェネリッククラスの作成方法については、ウェブ上にたくさんのチュートリアルがあるはずですが、簡単な例を次に示します。

http://www.angelikalanger.com/GenericsFAQ/FAQSections/ParameterizedTypes.html#FAQ002

_class Pair<X,Y>  {  
  private X first; 
  private Y second;
  public Pair(X a1, Y a2) { 
    first  = a1; 
    second = a2; 
  } 
  public X getFirst()  { return first; } 
  public Y getSecond() { return second; } 
  public void setFirst(X arg)  { first = arg; } 
  public void setSecond(Y arg) { second = arg; } 
}
_
9
Bert F

次のようにComparableオブジェクトを「チェック」または定義する必要があります。

add(Comparable<Object> obj)
1
D.N.