web-dev-qa-db-fra.com

exception génératrice de transtypage Arrays.asList: Java.util.Arrays $ ArrayList ne peut pas être converti en Java.util.ArrayList

Je suis nouveau sur Java et j'essaie de comprendre pourquoi le premier extrait de code ne provoque pas cette exception, mais le second. Puisqu'un tableau de chaînes est passé dans Arrays.asList dans les deux cas, les deux extraits ne doivent-ils pas produire une exception ou ne pas produire une exception? 

Exception in thread "main" Java.lang.ClassCastException: Java.util.Arrays$ArrayList cannot be cast to Java.util.ArrayList

Premier extrait (ne fait pas exception):

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));

Deuxième extrait (cause de l'exception ci-dessus):

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add((ArrayList<String>) Arrays.asList(titles));

Le cas échéant, j'utilise JavaSE 1.6 dans Eclipse Helios.

37
DannyTree

Pour moi (avec Java 1.6.0_26), le premier extrait donne la même exception que le second. La raison en est que la méthode Arrays.asList(..) ne renvoie qu'une valeur List, pas nécessairement une ArrayList. Comme vous ne savez pas vraiment quel type (ou implémentation de) de List cette méthode est renvoyée, votre conversion en ArrayList<String> n'est pas sûre. Le résultat est que cela peut ou peut ne pas fonctionner comme prévu. Du point de vue du style de codage, une solution serait de changer votre déclaration stuff en:

List<List<String>> stuff = new ArrayList<List<String>>();

ce qui permettra d'ajouter tout ce qui sort de la méthode Arrays.asList(..).

31
Waldheinz

Si vous faites cela, vous ne recevrez aucun CCE:

ArrayList<ArrayList<String>> stuff = new ArrayList<ArrayList<String>>();
String[] titles = {"ticker", "grade", "score"};
stuff.add(new ArrayList<String>(Arrays.asList(titles)));

Comme le dit clairement l'erreur, la classe Java.util.ArrayList n'est pas identique à la classe statique imbriquée Java.util.Arrays.ArrayList. D'où l'exception. Nous surmontons cela en encapsulant la liste renvoyée en utilisant un Java.util.ArrayList.

10
adarshr

Le problème est que vous avez spécifié que votre liste doit contenir ArrayLists - et par implication aucune autre implémentation de la liste . Arrays.asList() renvoie sa propre implémentation d'une liste basée sur l'implémentation du paramètre array, qui peut ne pas être une ArrayList. C'est ton problème.

Plus généralement, vous avez un problème de style de code classique: vous devriez faire référence à interfaces abstraites (c'est-à-dire List) et non à des implémentations concrètes (c'est-à-dire ArrayList). Voici à quoi votre code devrait ressembler:

List<List<String>> stuff = new ArrayList<List<String>>();
String[] titles = { "ticker", "grade", "score" };
stuff.add((List<String>) Arrays.asList(titles));

J'ai testé ce code et il fonctionne sans erreur.

10
Bohemian

Pas besoin de lancer manuellement. Ce code simple peut vous aider,

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

Si vous souhaitez utiliser votre propriété en tant qu'ArrayList <'T'>, il vous suffit de vous y déclarer et de créer un getter.

    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;
    }

Initialise la variable et utilise la méthode [addAll (Collection collection)] ( http://developer.Android.com/intl/pt-br/reference/Java/util/ArrayList.html#addAll(Java.util.Collection ))

1
GFPF

À l'aide d'un débogueur, j'ai déterminé qu'Array.asList (titres) renvoyait une "Arrays $ ArrayList" (c'est-à-dire une classe interne de la classe Arrays) plutôt qu'un fichier Java.util.ArrayList.

Il est toujours préférable d’utiliser l’interface située à gauche des expressions, dans ce cas-ci la liste plutôt que le tableau concret ArrayList. Cela fonctionne bien:

    List<List<String>> stuff = new ArrayList<List<String>>();
    String[] titles = {"ticker", "grade", "score"};
    stuff.add((List<String>) Arrays.asList(titles));
1
Ant Kutschera

Tout d'abord, Arrays.asList () ne doit jamais être converti en ArrayList. Deuxièmement, depuis que les génériques ont été introduits dans le langage de programmation Java, la conversion en langage de programmation est toujours d'actualité lorsque vous utilisez des API pré-génériques héritées.

Troisièmement, jamais utilisez des classes concrètes à gauche de l'opérateur d'affectation. 

En bout de ligne, disons 

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));

et soyez heureux.

0
AlexR