web-dev-qa-db-ja.com

Arrays.asListをキャストすると例外が発生します:Java.util.Arrays $ ArrayListをJava.util.ArrayListにキャストできません

私は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を使用しています。

38
DannyTree

私にとって(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(..)メソッドから出力されるものはすべて追加できます。

30
Waldheinz

これを行うと、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を使用して返されたリストをラップすることにより、これを克服します。

10
adarshr

問題は、リストに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));

このコードをテストしましたが、エラーなしで実行されます。

10
Bohemian

手動でキャストする必要はありません。この簡単なコードが役立つ場合があります。

List stuff = new ArrayList();
String line = "a,b,cdef,g";
String delim = ",";
stuff.addAll(Arrays.asList(line.split(delim)));
8
Srinivasan.S

プロパティを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 )))

1
GFPF

デバッガを使用して、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));
1
Ant Kutschera

まず、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));

そして幸せになる。

0
AlexR