私はJavaが初めてであり、最初のコードスニペットがこの例外を引き起こさないが、2番目のコードスニペットが原因である理由を理解しようとしています。 、両方のスニペットは例外を生成するべきではないのですか?
Exception in thread "main" Java.lang.ClassCastException: Java.util.Arrays$ArrayList cannot be cast to Java.util.ArrayList
最初のスニペット(例外は発生しません):
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add((ArrayList<String>) Arrays.asList(pieces));
2番目のスニペット(上記の例外が発生します):
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((ArrayList<String>) Arrays.asList(titles));
必要に応じて、Eclipse HeliosでJavaSE 1.6を使用しています。
私にとって(Java 1.6.0_26)を使用すると、最初のスニペットは2番目のスニペットと同じ例外を返します。理由は Arrays.asList(..)
メソッドはList
を返すだけで、必ずしもArrayList
を返すわけではありません。そのメソッドが返すList
の種類(または implementation of )が本当にわからないため、ArrayList<String>
へのキャストは安全ではありませんコーディングスタイルの観点から、これに対する適切な修正は、stuff
宣言を次のように変更することです。
List<List<String>> stuff = new ArrayList<List<String>>();
Arrays.asList(..)
メソッドから出力されるものはすべて追加できます。
これを行うと、CCEを取得できません。
ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));
エラーが明確に述べているように、クラスJava.util.ArrayList
はネストされた静的クラスJava.util.Arrays.ArrayList
と同じではありません。したがって、例外。 Java.util.ArrayList
を使用して返されたリストをラップすることにより、これを克服します。
問題は、リストにArrayLists
を含めるように指定したことと、暗黙的に他のリストの実装なしです。 Arrays.asList()
は、配列パラメーターの実装に基づいて、Listの独自の実装を返します。これは、がArrayListでない場合があります。それはあなたの問題だ。
より広範には、古典的なコードスタイルの問題があります。具体的な実装ではなく、抽象的なインターフェイス(つまりList
)を参照する必要があります(すなわちArrayList
)。コードは次のようになります。
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = { "ticker", "grade", "score" };
stuff.add((List<String>) Arrays.asList(titles));
このコードをテストしましたが、エラーなしで実行されます。
手動でキャストする必要はありません。この簡単なコードが役立つ場合があります。
List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
プロパティをArrayList <'T'>として使用する場合は、そこで宣言してゲッターを作成するだけです。
private static ArrayList<String> bandsArrayList;
public ArrayList<String> getBandsArrayList() {
if (bandsArrayList == null) {
bandsArrayList = new ArrayList<>();
String[] bands = {"Metallica", "Iron Maiden", "Nirvana"};
bandsArrayList.addAll(Arrays.asList(bands));
}
return bandsArrayList;
}
変数を初期化し、メソッド[addAll(コレクションコレクション)]( http://developer.Android.com/intl/pt-br/reference/Java/util/ArrayList.html#addAll(Java.util .Collection )))
デバッガを使用して、Array.asList(titles)がJava.util.ArrayListではなく「Arrays $ ArrayList」(つまり、Arraysクラスの内部クラス)を返すことを確認しました。
式の左側にあるインターフェイス、この場合は具象ArrayListではなくListを使用することが常に最善です。これはうまくいきます:
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((List<String>) Arrays.asList(titles));
まず、Arrays.asList()をArrayListにキャストしないでください。第二に、ジェネリックがJavaに導入されたため、プログラミング言語のキャスティングは、従来のジェネリック前のAPIを使用する場合に引き続き関連します。
第三に、never代入演算子の左側で具体的なクラスを使用します。
要するに、言う
List<List<String>> stuff = new ArrayList<List<String>>();
String line = "a,b,cdef,g";
String delim = ",";
String[] pieces = line.split(delim);
stuff.add(Arrays.asList(pieces));
List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(Arrays.asList(titles));
そして幸せになる。