そのコードは常にスローすべきではありませんClassCastExceptionか?Sun Java 6 コンパイラーとランタイム (Linux 上) を使用することで実現します。Integers を s としてキャストしていますString。作成されたイテレータは になりますがIterator<String>、最初の要素である にアクセスしようとするIntegerため、失敗します。
配列を次のように変更すると、これはより明確になります。
return Arrays.asList("one", 2, 3);
String最初の要素は aであり、出力が表示されるため、ループは実際には最初の要素に対して機能します。それはIterator<String>文字列ではないため、2番目のもので失敗します。
List特定のコードではなくジェネリックを使用するだけで、コードは機能します。
List list = getObjects();
for (Object o : list) {
System.out.println(o);
}
...または、もちろん、使用する場合はList<Integer>、内容がIntegers であるためです。あなたが今やっていることは、コンパイラの警告を引き起こします — Note: Generics.java uses unchecked or unsafe operations. — そしてそれには正当な理由があります。
この変更も機能します。
for (Object o : (List)list)
Iterator...おそらく、その時点で ではなくを扱っているためですIterator<String>。
bozho は、Windows XP ではこのエラーが表示されないと述べています (どのコンパイラとランタイムについては言及していませんが、私は Sun のものだと推測しています)。ここでは実装の機密性について説明しますが、結論は次のとおりです。 of と対話するために使用しないでList<String>ください。:-)ListInteger
コンパイルしているファイルは次のとおりです。
import java.util.Arrays;
import java.util.List;
public class Generics {
static List getObjects() {
return Arrays.asList("one", 2, 3);
}
public static void main(String[] args) {
List<String> list = getObjects();
for (Object o : list) { // ClassCastException?
System.out.println(o);
}
}
}
コンパイルは次のとおりです。
tjc@forge:~/temp$ javac Generics.java
注: Generics.java は、未チェックまたは安全でない操作を使用します。
注: 詳細については、-Xlint:unchecked で再コンパイルしてください。
実行は次のとおりです。
tjc@forge:~/temp$ Javaジェネリック
1
スレッド「メイン」の例外 java.lang.ClassCastException: java.lang.Integer は java.lang.String にキャストできません
Generics.main (Generics.java:12) で
行 12 はforステートメントです。に変更したため、最初の要素が出力されたことに注意してくださいString。他は出力しませんでした。(そして、その変更を行う前に、すぐに失敗しました。)
私が使用しているコンパイラは次のとおりです。
tjc@forge:~/temp$ which javac
/usr/bin/javac
tjc@forge:~/temp$ ll /usr/bin/javac
lrwxrwxrwx 1 ルート root 23 2010-09-30 16:37 /usr/bin/javac -> /etc/alternatives/javac*
tjc@forge:~/temp$ ll /etc/alternatives/javac
lrwxrwxrwx 1 ルート root 33 2010-09-30 16:37 /etc/alternatives/javac -> /usr/lib/jvm/java-6-sun/bin/javac*
以下は、以下を示す逆アセンブリcheckcastです。
tjc@forge:~/temp$ javap -c ジェネリック
「Generics.java」からコンパイル
public class Generics extends java.lang.Object{
パブリック ジェネリック ();
コード:
0: aload_0
1: 特別な #1 を呼び出します。//メソッド java/lang/Object."":()V
4: 戻る
static java.util.List getObjects();
コード:
0: アイコンスト_3
1: 新しい配列 #2; //クラス java/io/Serializable
4: 複製
5: アイコンスト_0
6: ldc #3; //文字列 1
8: アストア
9: 重複
10: アイコンスト_1
11: アイコンスト_2
12: インボークスタティック #4; //メソッド java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
15: アーストア
16: デュプ
17: アイコンスト_2
18: アイコンスト_3
19: インボークスタティック #4; //メソッド java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
22:アストアー
23: インボークスタティック #5; //メソッド java/util/Arrays.asList:([Ljava/lang/Object;)Ljava/util/List;
26: リターン
public static void main(java.lang.String[]);
コード:
0: インボークスタティック #6; //メソッド getObjects:()Ljava/util/List;
3: アストア_1
4: aload_1
5: 呼び出しインターフェイス #7、1; //InterfaceMethod java/util/List.iterator:()Ljava/util/Iterator;
10: アストア_2
11: aload_2
12: 呼び出しインターフェイス #8、1; //InterfaceMethod java/util/Iterator.hasNext:()Z
17: ifeq 40
20: アロード_2
21: 呼び出しインターフェイス #9、1; //InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
26: チェックキャスト #10; //クラス java/lang/String
29: アストア_3
30: getstatic #11; //フィールド java/lang/System.out:Ljava/io/PrintStream;
33: アロード_3
34: インボークバーチャル #12; //メソッド java/io/PrintStream.println:(Ljava/lang/Object;)V
37: 後藤11
40: 戻る
}
繰り返しになりますが、最終List<String>的には次のListようにする必要がありStringます。:-)