dポイントプレゼントキャンペーン実施中!

以下のメソッドを含むプログラムをEclipseで作成している際に次のような警告が発生しました。
型の安全性:型Comparator の式は、未検査の型変換を使用してComparator<? super T>に準拠するようにする必要があります。

型の安全性:型 Arrays の総称メソッド sort(T[], Comparator<? super T>)の未検査の呼び出し sort(Object[],Comparator)がありました。

コンパイルして実行する分には、なんら問題ないのですが、この警告の意味と解決策が分からないままにしておくのは気持ち悪いので、分かる方がいらしたら教えてください。

static void sortName(){
 String array[] = new String[4];
 array[0] = "abba";
 array[1] = "abab";
 array[2] = "aaaa";
 array[3] = "aabb";

 Comparator asc = new Comparator() {
  public int compare(Object obj0, Object obj1) {
   String nameKana0 = (String)obj0;
   String nameKana1 = (String)obj1;
   int ret = 0;
   ret = nameKana0.compareTo(nameKana1);

   return ret;
 }
 };
 Comparator comparator = asc;
 Arrays.sort(array, comparator); // 配列をソート

 for (int i = 0; i < array.length; i++)
  System.out.println(array[i]);
}

A 回答 (2件)

#1さんの通り、SDK1.4に戻せば警告は発生しなくなります。



そもそも、JDK 5.0 から何故このような警告が発生するようになったかを考えてみます。

Comparator匿名クラス内のcompare()メソッド内で引数Object obj1, obj2 を(String)にキャストしていますよね。しかし、これがもしString型で無い場合はどうなるでしょう。

例えば、Arrays.sort(array, comparator); のarrayが String[] ではなく、極端な話 Integer[] の場合です。 IntegerはObjectを継承しているので構文的にも間違いはなく、コンパイルも問題なく通りますがおそらく実行時にIntegerインスタンスをStringにキャスト出来ず、Cast関係の例外が発生します。

このような現象を回避するのがGenericsです。
Comparatorの匿名クラスを作成する際に、「何(のオブジェクト)に関するComparatorなのか」をコンパイラに教えてやるわけです。そうすることで誤って型の一致しない配列を渡してやってもコンパイルの時点で 検出することが出来ます。

警告を発しないように対処したコードは以下の用になります。

import java.util.*;

public class Test {

 public static void sortName(){
 String array[] = new String[4];
  array[0] = "abba";
  array[1] = "abab";
  array[2] = "aaaa";
  array[3] = "aabb";

  Comparator<String> asc = new Comparator<String>() {
   public int compare(String obj0, String obj1) {
    return obj0.compareTo(obj1);
   }
  };

  Comparator<String> comparator = asc;
  Arrays.sort(array, comparator); // 配列をソート
  for (int i = 0; i < array.length; i++)
   System.out.println(array[i]);
 }

 public static void main(String[] argv) {
  Test.sortName();
 }
}

Genericsの別の利点としていちいちキャストしなくてもよくなることがあげられます。 Vector や ArrayList 等を使うときにも何かと便利です。

ArrayList<String> aryString = new ArrayList<String>();
for (int i=0; i<10; i++)
 aryString.add("No." + i);
for (int i=0; i<aryString.size(); i++)
 System.out.println ( aryString.get(i) ); // キャスト無しで使える

参考URL:http://www.javaworld.jp/technology_and_programmi …
    • good
    • 1
この回答へのお礼

大変分かりやすく説明していただきありがとうございます。
おかげで分からない箇所がわかりました。ありがとうございます。

お礼日時:2006/10/27 11:36

JDKのバージョンを1.5から1.4以下に落とせばエラーは消えるとおもいます。


JDK1.5(JAVA 5.0)から導入されたGenerics により、Object型を使うことによる「何でもOK」を認めない仕様になっています。
必ずString型の変数しか入れないコンパレータならば、
<String>宣言してあげればよろしいかと。

参考URL:http://journal.mycom.co.jp/column/java/021/
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています